github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/pkg/hook/hook_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 hook 18 19 import ( 20 "encoding/json" 21 "net/http/httptest" 22 "testing" 23 "time" 24 25 "sigs.k8s.io/prow/pkg/bugzilla" 26 "sigs.k8s.io/prow/pkg/config" 27 "sigs.k8s.io/prow/pkg/github" 28 "sigs.k8s.io/prow/pkg/githubeventserver" 29 "sigs.k8s.io/prow/pkg/jira/fakejira" 30 "sigs.k8s.io/prow/pkg/phony" 31 "sigs.k8s.io/prow/pkg/plugins" 32 "sigs.k8s.io/prow/pkg/plugins/ownersconfig" 33 "sigs.k8s.io/prow/pkg/repoowners" 34 ) 35 36 var ice = github.IssueCommentEvent{ 37 Action: "reopened", 38 Repo: github.Repo{ 39 Owner: github.User{ 40 Login: "foo", 41 }, 42 Name: "bar", 43 FullName: "foo/bar", 44 }, 45 } 46 47 var repoLevelSecret = ` 48 '*': 49 - value: key1 50 created_at: 2019-10-02T15:00:00Z 51 - value: key2 52 created_at: 2020-10-02T15:00:00Z 53 foo/bar: 54 - value: 123abc 55 created_at: 2019-10-02T15:00:00Z 56 - value: key6 57 created_at: 2020-10-02T15:00:00Z 58 ` 59 60 var orgLevelSecret = ` 61 '*': 62 - value: key1 63 created_at: 2019-10-02T15:00:00Z 64 - value: key2 65 created_at: 2020-10-02T15:00:00Z 66 foo: 67 - value: 123abc 68 created_at: 2019-10-02T15:00:00Z 69 - value: key4 70 created_at: 2020-10-02T15:00:00Z 71 ` 72 73 var globalSecret = ` 74 '*': 75 - value: 123abc 76 created_at: 2019-10-02T15:00:00Z 77 - value: key2 78 created_at: 2020-10-02T15:00:00Z 79 ` 80 81 var missingMatchingSecret = ` 82 somerandom: 83 - value: 123abc 84 created_at: 2019-10-02T15:00:00Z 85 - value: key2 86 created_at: 2020-10-02T15:00:00Z 87 ` 88 89 var secretInOldFormat = `123abc` 90 91 // TestHook sets up a hook.Server and then sends a fake webhook at it. It then 92 // ensures that a fake plugin is called. 93 func TestHook(t *testing.T) { 94 called := make(chan bool, 1) 95 payload, err := json.Marshal(&ice) 96 if err != nil { 97 t.Fatalf("Marshalling ICE: %v", err) 98 } 99 plugins.RegisterIssueHandler( 100 "baz", 101 func(pc plugins.Agent, ie github.IssueEvent) error { 102 called <- true 103 return nil 104 }, 105 nil, 106 ) 107 pa := &plugins.ConfigAgent{} 108 pa.Set(&plugins.Configuration{Plugins: plugins.Plugins{"foo/bar": {Plugins: []string{"baz"}}}}) 109 ca := &config.Agent{} 110 clientAgent := &plugins.ClientAgent{ 111 GitHubClient: github.NewFakeClient(), 112 OwnersClient: repoowners.NewClient(nil, nil, func(org, repo string) bool { return false }, func(org, repo string) bool { return false }, func() *config.OwnersDirDenylist { return &config.OwnersDirDenylist{} }, ownersconfig.FakeResolver), 113 JiraClient: &fakejira.FakeClient{}, 114 BugzillaClient: &bugzilla.Fake{}, 115 } 116 metrics := githubeventserver.NewMetrics() 117 var testcases = []struct { 118 name string 119 secret []byte 120 tokenGenerator func() []byte 121 shouldSucceed bool 122 }{ 123 { 124 name: "Token present at repository level.", 125 secret: []byte("123abc"), 126 tokenGenerator: func() []byte { 127 return []byte(repoLevelSecret) 128 }, 129 shouldSucceed: true, 130 }, 131 { 132 name: "Token present at org level.", 133 secret: []byte("123abc"), 134 tokenGenerator: func() []byte { 135 return []byte(orgLevelSecret) 136 }, 137 shouldSucceed: true, 138 }, 139 { 140 name: "Token present at global level.", 141 secret: []byte("123abc"), 142 tokenGenerator: func() []byte { 143 return []byte(globalSecret) 144 }, 145 shouldSucceed: true, 146 }, 147 { 148 name: "Token not matching anywhere (wildcard token missing).", 149 secret: []byte("123abc"), 150 tokenGenerator: func() []byte { 151 return []byte(missingMatchingSecret) 152 }, 153 shouldSucceed: false, 154 }, 155 { 156 name: "Secret in old format.", 157 secret: []byte("123abc"), 158 tokenGenerator: func() []byte { 159 return []byte(secretInOldFormat) 160 }, 161 shouldSucceed: true, 162 }, 163 } 164 165 for _, tc := range testcases { 166 t.Logf("Running scenario %q", tc.name) 167 168 s := httptest.NewServer(&Server{ 169 ClientAgent: clientAgent, 170 Plugins: pa, 171 ConfigAgent: ca, 172 Metrics: metrics, 173 RepoEnabled: func(org, repo string) bool { return true }, 174 TokenGenerator: tc.tokenGenerator, 175 }) 176 defer s.Close() 177 if err := phony.SendHook(s.URL, "issues", payload, tc.secret); (err != nil) == tc.shouldSucceed { 178 t.Fatalf("Error sending hook: %v", err) 179 } 180 } 181 182 select { 183 case <-called: // All good. 184 case <-time.After(time.Second): 185 t.Error("Plugin not called after one second.") 186 } 187 }