github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/pkg/plugins/skip/skip_test.go (about)

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package skip
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  
    23  	"github.com/sirupsen/logrus"
    24  
    25  	"sigs.k8s.io/prow/pkg/config"
    26  	"sigs.k8s.io/prow/pkg/github"
    27  	"sigs.k8s.io/prow/pkg/github/fakegithub"
    28  )
    29  
    30  func TestSkipStatus(t *testing.T) {
    31  	tests := []struct {
    32  		name string
    33  
    34  		presubmits     []config.Presubmit
    35  		sha            string
    36  		event          *github.GenericCommentEvent
    37  		prChanges      map[int][]github.PullRequestChange
    38  		existing       []github.Status
    39  		combinedStatus string
    40  		expected       []github.Status
    41  	}{
    42  		{
    43  			name: "required contexts should not be skipped regardless of their state",
    44  
    45  			presubmits: []config.Presubmit{
    46  				{
    47  					Reporter: config.Reporter{
    48  						Context: "passing-tests",
    49  					},
    50  				},
    51  				{
    52  					Reporter: config.Reporter{
    53  						Context: "failed-tests",
    54  					},
    55  				},
    56  				{
    57  					Reporter: config.Reporter{
    58  						Context: "pending-tests",
    59  					},
    60  				},
    61  			},
    62  			sha: "shalala",
    63  			event: &github.GenericCommentEvent{
    64  				IsPR:       true,
    65  				IssueState: "open",
    66  				Action:     github.GenericCommentActionCreated,
    67  				Body:       "/skip",
    68  				Number:     1,
    69  				Repo:       github.Repo{Owner: github.User{Login: "org"}, Name: "repo"},
    70  			},
    71  			existing: []github.Status{
    72  				{
    73  					Context: "passing-tests",
    74  					State:   github.StatusSuccess,
    75  				},
    76  				{
    77  					Context: "failed-tests",
    78  					State:   github.StatusFailure,
    79  				},
    80  				{
    81  					Context: "pending-tests",
    82  					State:   github.StatusPending,
    83  				},
    84  			},
    85  
    86  			expected: []github.Status{
    87  				{
    88  					Context: "passing-tests",
    89  					State:   github.StatusSuccess,
    90  				},
    91  				{
    92  					Context: "failed-tests",
    93  					State:   github.StatusFailure,
    94  				},
    95  				{
    96  					Context: "pending-tests",
    97  					State:   github.StatusPending,
    98  				},
    99  			},
   100  		},
   101  		{
   102  			name: "optional contexts that have failed or are pending should be skipped",
   103  
   104  			presubmits: []config.Presubmit{
   105  				{
   106  					Optional: true,
   107  					Reporter: config.Reporter{
   108  						Context: "failed-tests",
   109  					},
   110  				},
   111  				{
   112  					Optional: true,
   113  					Reporter: config.Reporter{
   114  						Context: "pending-tests",
   115  					},
   116  				},
   117  			},
   118  			sha: "shalala",
   119  			event: &github.GenericCommentEvent{
   120  				IsPR:       true,
   121  				IssueState: "open",
   122  				Action:     github.GenericCommentActionCreated,
   123  				Body:       "/skip",
   124  				Number:     1,
   125  				Repo:       github.Repo{Owner: github.User{Login: "org"}, Name: "repo"},
   126  			},
   127  			existing: []github.Status{
   128  				{
   129  					State:   github.StatusFailure,
   130  					Context: "failed-tests",
   131  				},
   132  				{
   133  					State:   github.StatusPending,
   134  					Context: "pending-tests",
   135  				},
   136  			},
   137  
   138  			expected: []github.Status{
   139  				{
   140  					State:       github.StatusSuccess,
   141  					Description: "Skipped",
   142  					Context:     "failed-tests",
   143  				},
   144  				{
   145  					State:       github.StatusSuccess,
   146  					Description: "Skipped",
   147  					Context:     "pending-tests",
   148  				},
   149  			},
   150  		},
   151  		{
   152  			name: "optional contexts that have not posted a context should not be skipped",
   153  
   154  			presubmits: []config.Presubmit{
   155  				{
   156  					Optional: true,
   157  					Reporter: config.Reporter{
   158  						Context: "untriggered-tests",
   159  					},
   160  				},
   161  			},
   162  			sha: "shalala",
   163  			event: &github.GenericCommentEvent{
   164  				IsPR:       true,
   165  				IssueState: "open",
   166  				Action:     github.GenericCommentActionCreated,
   167  				Body:       "/skip",
   168  				Number:     1,
   169  				Repo:       github.Repo{Owner: github.User{Login: "org"}, Name: "repo"},
   170  			},
   171  			existing: []github.Status{},
   172  
   173  			expected: []github.Status{},
   174  		},
   175  		{
   176  			name: "optional contexts that have succeeded should not be skipped",
   177  
   178  			presubmits: []config.Presubmit{
   179  				{
   180  					Optional: true,
   181  					Reporter: config.Reporter{
   182  						Context: "succeeded-tests",
   183  					},
   184  				},
   185  			},
   186  			sha: "shalala",
   187  			event: &github.GenericCommentEvent{
   188  				IsPR:       true,
   189  				IssueState: "open",
   190  				Action:     github.GenericCommentActionCreated,
   191  				Body:       "/skip",
   192  				Number:     1,
   193  				Repo:       github.Repo{Owner: github.User{Login: "org"}, Name: "repo"},
   194  			},
   195  			existing: []github.Status{
   196  				{
   197  					State:   github.StatusSuccess,
   198  					Context: "succeeded-tests",
   199  				},
   200  			},
   201  
   202  			expected: []github.Status{
   203  				{
   204  					State:   github.StatusSuccess,
   205  					Context: "succeeded-tests",
   206  				},
   207  			},
   208  		},
   209  		{
   210  			name: "optional tests that have failed but will be handled by trigger should not be skipped",
   211  
   212  			presubmits: []config.Presubmit{
   213  				{
   214  					Optional:     true,
   215  					Trigger:      `(?m)^/test (?:.*? )?job(?: .*?)?$`,
   216  					RerunCommand: "/test job",
   217  					Reporter: config.Reporter{
   218  						Context: "failed-tests",
   219  					},
   220  				},
   221  			},
   222  			sha: "shalala",
   223  			event: &github.GenericCommentEvent{
   224  				IsPR:       true,
   225  				IssueState: "open",
   226  				Action:     github.GenericCommentActionCreated,
   227  				Body: `/skip
   228  /test job`,
   229  				Number: 1,
   230  				Repo:   github.Repo{Owner: github.User{Login: "org"}, Name: "repo"},
   231  			},
   232  			existing: []github.Status{
   233  				{
   234  					State:   github.StatusFailure,
   235  					Context: "failed-tests",
   236  				},
   237  			},
   238  			expected: []github.Status{
   239  				{
   240  					State:   github.StatusFailure,
   241  					Context: "failed-tests",
   242  				},
   243  			},
   244  		},
   245  		{
   246  			name: "no contexts should be skipped if the combined status is success",
   247  
   248  			presubmits: []config.Presubmit{
   249  				{
   250  					Optional: true,
   251  					Reporter: config.Reporter{
   252  						Context: "failed-tests",
   253  					},
   254  				},
   255  				{
   256  					Optional: true,
   257  					Reporter: config.Reporter{
   258  						Context: "pending-tests",
   259  					},
   260  				},
   261  			},
   262  			sha:            "shalala",
   263  			combinedStatus: github.StatusSuccess,
   264  			event: &github.GenericCommentEvent{
   265  				IsPR:       true,
   266  				IssueState: "open",
   267  				Action:     github.GenericCommentActionCreated,
   268  				Body:       "/skip",
   269  				Number:     1,
   270  				Repo:       github.Repo{Owner: github.User{Login: "org"}, Name: "repo"},
   271  			},
   272  			existing: []github.Status{
   273  				{
   274  					State:   github.StatusFailure,
   275  					Context: "failed-tests",
   276  				},
   277  				{
   278  					State:   github.StatusPending,
   279  					Context: "pending-tests",
   280  				},
   281  			},
   282  			expected: []github.Status{
   283  				{
   284  					State:   github.StatusFailure,
   285  					Context: "failed-tests",
   286  				},
   287  				{
   288  					State:   github.StatusPending,
   289  					Context: "pending-tests",
   290  				},
   291  			},
   292  		},
   293  	}
   294  	for _, test := range tests {
   295  		if err := config.SetPresubmitRegexes(test.presubmits); err != nil {
   296  			t.Fatalf("%s: could not set presubmit regexes: %v", test.name, err)
   297  		}
   298  
   299  		fghc := fakegithub.NewFakeClient()
   300  		fghc.IssueComments = make(map[int][]github.IssueComment)
   301  		fghc.PullRequests = map[int]*github.PullRequest{
   302  			test.event.Number: {
   303  				Head: github.PullRequestBranch{
   304  					SHA: test.sha,
   305  				},
   306  			},
   307  		}
   308  		fghc.PullRequestChanges = test.prChanges
   309  		fghc.CreatedStatuses = map[string][]github.Status{
   310  			test.sha: test.existing,
   311  		}
   312  		fghc.CombinedStatuses = map[string]*github.CombinedStatus{
   313  			test.sha: {
   314  				State:    test.combinedStatus,
   315  				Statuses: test.existing,
   316  			},
   317  		}
   318  		l := logrus.WithField("plugin", pluginName)
   319  
   320  		c := &config.Config{
   321  			JobConfig: config.JobConfig{
   322  				PresubmitsStatic: map[string][]config.Presubmit{"org/repo": test.presubmits},
   323  			},
   324  		}
   325  
   326  		if err := handle(fghc, l, test.event, c, nil, true); err != nil {
   327  			t.Errorf("%s: unexpected error: %v", test.name, err)
   328  			continue
   329  		}
   330  
   331  		// Check that the correct statuses have been updated.
   332  		created := fghc.CreatedStatuses[test.sha]
   333  		if len(test.expected) != len(created) {
   334  			t.Errorf("%s: status mismatch: expected:\n%+v\ngot:\n%+v", test.name, test.expected, created)
   335  			continue
   336  		}
   337  		for _, got := range created {
   338  			var found bool
   339  			for _, exp := range test.expected {
   340  				if exp.Context == got.Context {
   341  					found = true
   342  					if !reflect.DeepEqual(exp, got) {
   343  						t.Errorf("%s: expected status: %v, got: %v", test.name, exp, got)
   344  					}
   345  				}
   346  			}
   347  			if !found {
   348  				t.Errorf("%s: expected context %q in the results: %v", test.name, got.Context, created)
   349  				break
   350  			}
   351  		}
   352  	}
   353  }