...

Source file src/github.com/chaos-mesh/chaos-mesh/pkg/workflow/scheduler/serial_scheduler_test.go

Documentation: github.com/chaos-mesh/chaos-mesh/pkg/workflow/scheduler

     1  // Copyright 2021 Chaos Mesh Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package scheduler
    15  
    16  import (
    17  	"context"
    18  	"errors"
    19  	"testing"
    20  
    21  	"github.com/golang/mock/gomock"
    22  	"github.com/stretchr/testify/assert"
    23  
    24  	workflowerrors "github.com/chaos-mesh/chaos-mesh/pkg/workflow/errors"
    25  	"github.com/chaos-mesh/chaos-mesh/pkg/workflow/mock/model/mock_node"
    26  	"github.com/chaos-mesh/chaos-mesh/pkg/workflow/mock/model/mock_template"
    27  	"github.com/chaos-mesh/chaos-mesh/pkg/workflow/mock/model/mock_workflow"
    28  	"github.com/chaos-mesh/chaos-mesh/pkg/workflow/model/template"
    29  )
    30  
    31  func TestScheduleWithSerial(t *testing.T) {
    32  
    33  	tests := []struct {
    34  		name                       string
    35  		childrenTemplates          []string
    36  		succeedChildren            int
    37  		expectedScheduledTemplates []string
    38  		expectedError              error
    39  	}{
    40  		{
    41  			name:                       "no-schedule",
    42  			childrenTemplates:          nil,
    43  			succeedChildren:            0,
    44  			expectedScheduledTemplates: nil,
    45  			expectedError:              workflowerrors.ErrNoMoreTemplateInSerialTemplate,
    46  		}, {
    47  			name:                       "alternative-no-schedule",
    48  			childrenTemplates:          []string{},
    49  			succeedChildren:            0,
    50  			expectedScheduledTemplates: nil,
    51  			expectedError:              workflowerrors.ErrNoMoreTemplateInSerialTemplate,
    52  		}, {
    53  			name:                       "schedule-one-by-one-0",
    54  			childrenTemplates:          []string{"child-0", "child-1", "child-2"},
    55  			succeedChildren:            0,
    56  			expectedScheduledTemplates: []string{"child-0"},
    57  			expectedError:              nil,
    58  		}, {
    59  			name:                       "schedule-one-by-one-1",
    60  			childrenTemplates:          []string{"child-0", "child-1", "child-2"},
    61  			succeedChildren:            1,
    62  			expectedScheduledTemplates: []string{"child-1"},
    63  			expectedError:              nil,
    64  		}, {
    65  			name:                       "schedule-one-by-one-2",
    66  			childrenTemplates:          []string{"child-0", "child-1", "child-2"},
    67  			succeedChildren:            2,
    68  			expectedScheduledTemplates: []string{"child-2"},
    69  			expectedError:              nil,
    70  		}, {
    71  			name:                       "schedule-one-by-one-final",
    72  			childrenTemplates:          []string{"child-0", "child-1", "child-2"},
    73  			succeedChildren:            3,
    74  			expectedScheduledTemplates: nil,
    75  			expectedError:              workflowerrors.ErrNoMoreTemplateInSerialTemplate,
    76  		}, {
    77  			name:                       "schedule-duplicated-template-0",
    78  			childrenTemplates:          []string{"child-0", "child-1", "child-0", "child-1"},
    79  			succeedChildren:            0,
    80  			expectedScheduledTemplates: []string{"child-0"},
    81  			expectedError:              nil,
    82  		}, {
    83  			name:                       "schedule-duplicated-template-1",
    84  			childrenTemplates:          []string{"child-0", "child-1", "child-0", "child-1"},
    85  			succeedChildren:            1,
    86  			expectedScheduledTemplates: []string{"child-1"},
    87  			expectedError:              nil,
    88  		}, {
    89  			name:                       "schedule-duplicated-template-2",
    90  			childrenTemplates:          []string{"child-0", "child-1", "child-0", "child-1"},
    91  			succeedChildren:            2,
    92  			expectedScheduledTemplates: []string{"child-0"},
    93  			expectedError:              nil,
    94  		}, {
    95  			name:                       "schedule-duplicated-template-3",
    96  			childrenTemplates:          []string{"child-0", "child-1", "child-0", "child-1"},
    97  			succeedChildren:            3,
    98  			expectedScheduledTemplates: []string{"child-1"},
    99  			expectedError:              nil,
   100  		}, {
   101  			name:                       "schedule-duplicated-template-4",
   102  			childrenTemplates:          []string{"child-0", "child-1", "child-0", "child-1"},
   103  			succeedChildren:            4,
   104  			expectedScheduledTemplates: nil,
   105  			expectedError:              workflowerrors.ErrNoMoreTemplateInSerialTemplate,
   106  		},
   107  	}
   108  	for _, test := range tests {
   109  		t.Run(test.name, func(t *testing.T) {
   110  			mockctl := gomock.NewController(t)
   111  			const serialTemplateName = "mock-serial"
   112  			const serialNodeName = serialTemplateName + "-0000"
   113  			const workflowName = "mock-workflow"
   114  
   115  			mockSerialTemplate := mock_template.NewMockSerialTemplate(mockctl)
   116  			mockSerialTemplate.EXPECT().TemplateType().Return(template.Serial).AnyTimes()
   117  			mockSerialTemplate.EXPECT().SerialChildrenList().Return(test.childrenTemplates).AnyTimes()
   118  
   119  			mockWorkflowSpec := mock_workflow.NewMockWorkflowSpec(mockctl)
   120  			mockWorkflowSpec.EXPECT().Name().Return(workflowName).AnyTimes()
   121  
   122  			mockTreeNode := mock_node.NewMockNodeTreeNode(mockctl)
   123  			nodeTreeChildren := mock_node.NewMockNodeTreeChildren(mockctl)
   124  			mockTreeNode.EXPECT().Name().Return(serialNodeName).AnyTimes()
   125  			mockTreeNode.EXPECT().Children().Return(nodeTreeChildren).AnyTimes()
   126  			mockTreeNode.EXPECT().TemplateName().Return(serialTemplateName).AnyTimes()
   127  			nodeTreeChildren.EXPECT().Length().Return(test.succeedChildren).AnyTimes()
   128  
   129  			mockNode := mock_node.NewMockNode(mockctl)
   130  			mockNode.EXPECT().Name().Return(serialNodeName).AnyTimes()
   131  			mockNode.EXPECT().TemplateName().Return(serialTemplateName).AnyTimes()
   132  
   133  			mockWorkflowSpec.EXPECT().FetchTemplateByName(gomock.Eq(serialTemplateName)).Return(mockSerialTemplate, nil).AnyTimes()
   134  			for _, childTemplate := range test.childrenTemplates {
   135  				mockChildTemplate := mock_template.NewMockSerialTemplate(mockctl)
   136  				mockChildTemplate.EXPECT().Name().Return(childTemplate).AnyTimes()
   137  				mockWorkflowSpec.EXPECT().FetchTemplateByName(gomock.Eq(childTemplate)).Return(mockChildTemplate, nil).AnyTimes()
   138  			}
   139  
   140  			scheduler := NewSerialScheduler(mockWorkflowSpec, mockNode, mockTreeNode)
   141  			nextTemplates, parentNodeName, err := scheduler.ScheduleNext(context.TODO())
   142  			if test.expectedError != nil {
   143  				assert.Error(t, err)
   144  				assert.True(t, errors.Is(err, test.expectedError))
   145  			} else {
   146  				assert.NoError(t, err)
   147  				assert.Equal(t, serialNodeName, parentNodeName)
   148  				var names []string
   149  				for _, item := range nextTemplates {
   150  					names = append(names, item.Name())
   151  				}
   152  				assert.Equal(t, test.expectedScheduledTemplates, names)
   153  			}
   154  		})
   155  	}
   156  }
   157