github.com/abayer/test-infra@v0.0.5/prow/pluginhelp/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 "fmt" 21 "net/http" 22 "net/http/httptest" 23 "reflect" 24 "sort" 25 "testing" 26 27 "github.com/sirupsen/logrus" 28 29 "k8s.io/apimachinery/pkg/util/sets" 30 "k8s.io/test-infra/prow/github" 31 "k8s.io/test-infra/prow/pluginhelp" 32 "k8s.io/test-infra/prow/pluginhelp/externalplugins" 33 "k8s.io/test-infra/prow/plugins" 34 ) 35 36 type fakeGithubClient map[string][]string 37 38 func (fghc fakeGithubClient) GetRepos(org string, _ bool) ([]github.Repo, error) { 39 var repos []github.Repo 40 for _, repo := range fghc[org] { 41 repos = append(repos, github.Repo{FullName: fmt.Sprintf("%s/%s", org, repo)}) 42 } 43 return repos, nil 44 } 45 46 type fakePluginAgent plugins.Configuration 47 48 func (fpa fakePluginAgent) Config() *plugins.Configuration { 49 config := plugins.Configuration(fpa) 50 return &config 51 } 52 53 func TestGeneratePluginHelp(t *testing.T) { 54 orgToRepos := map[string][]string{"org1": {"repo1", "repo2", "repo3"}, "org2": {"repo1"}} 55 fghc := fakeGithubClient(orgToRepos) 56 57 normalHelp := map[string]pluginhelp.PluginHelp{ 58 "org-plugin": {Description: "org-plugin", Config: map[string]string{"": "overall config"}}, 59 "repo-plugin1": { 60 Description: "repo-plugin1", 61 Config: map[string]string{ 62 "org1/repo1": "repo1 config", 63 "org1/repo2": "repo2 config", 64 }, 65 }, 66 "repo-plugin2": {Description: "repo-plugin2", Config: map[string]string{}}, 67 "repo-plugin3": {Description: "repo-plugin3", Config: map[string]string{}}, 68 } 69 helpfulExternalHelp := pluginhelp.PluginHelp{Description: "helpful-external"} 70 noHelpSever := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 71 http.Error(w, "404 Not Found", http.StatusNotFound) 72 })) 73 defer noHelpSever.Close() 74 mux := http.NewServeMux() 75 externalplugins.ServeExternalPluginHelp( 76 mux, 77 logrus.WithField("plugin", "helpful-external"), 78 func(enabledRepos []string) (*pluginhelp.PluginHelp, error) { 79 if got, expected := enabledRepos, []string{"org1/repo1"}; !reflect.DeepEqual(got, expected) { 80 t.Errorf("Plugin 'helpful-external' expected to be enabled on repos %q, but got %q.", expected, got) 81 } 82 return &helpfulExternalHelp, nil 83 }, 84 ) 85 helpfulServer := httptest.NewServer(mux) 86 defer helpfulServer.Close() 87 88 config := &plugins.Configuration{ 89 Plugins: map[string][]string{ 90 "org1": {"org-plugin"}, 91 "org1/repo1": {"repo-plugin1", "no-help-plugin"}, 92 "org1/repo2": {"repo-plugin1", "repo-plugin2"}, 93 "org2/repo1": {"repo-plugin3"}, 94 }, 95 ExternalPlugins: map[string][]plugins.ExternalPlugin{ 96 "org1/repo1": { 97 {Name: "no-endpoint-external", Endpoint: "http://no-endpoint-external", Events: []string{"issue_comment"}}, 98 {Name: "no-help-external", Endpoint: noHelpSever.URL, Events: []string{"issue_comment"}}, 99 {Name: "helpful-external", Endpoint: helpfulServer.URL, Events: []string{"pull_request", "issue"}}, 100 }, 101 }, 102 } 103 fpa := fakePluginAgent(*config) 104 105 expectedAllRepos := []string{"org1/repo1", "org1/repo2", "org1/repo3", "org2/repo1"} 106 107 normalExpectedReposForPlugin := map[string][]string{ 108 "org-plugin": {"org1/repo1", "org1/repo2", "org1/repo3"}, 109 "repo-plugin1": {"org1/repo1", "org1/repo2"}, 110 "repo-plugin2": {"org1/repo2"}, 111 "repo-plugin3": {"org2/repo1"}, 112 "no-help-plugin": {"org1/repo1"}, 113 } 114 normalExpectedPluginsForRepo := map[string][]string{ 115 "": {"org-plugin", "repo-plugin1", "repo-plugin2", "repo-plugin3", "no-help-plugin"}, 116 "org1": {"org-plugin"}, 117 "org1/repo1": {"repo-plugin1", "no-help-plugin"}, 118 "org1/repo2": {"repo-plugin1", "repo-plugin2"}, 119 "org2/repo1": {"repo-plugin3"}, 120 } 121 normalExpectedEvents := map[string][]string{ 122 "org-plugin": {"issue_comment"}, 123 "repo-plugin1": {"issue"}, 124 "repo-plugin2": {"pull_request"}, 125 "repo-plugin3": {"pull_request_review", "pull_request_review_comment"}, 126 "no-help-plugin": {"issue_comment"}, 127 } 128 129 externalExpectedPluginsForRepo := map[string][]string{ 130 "": {"no-endpoint-external", "no-help-external", "helpful-external"}, 131 "org1/repo1": {"no-endpoint-external", "no-help-external", "helpful-external"}, 132 } 133 externalExpectedEvents := map[string][]string{ 134 "no-endpoint-external": {"issue_comment"}, 135 "no-help-external": {"issue_comment"}, 136 "helpful-external": {"pull_request", "issue"}, 137 } 138 139 registerNormalPlugins(t, normalExpectedEvents, normalHelp, normalExpectedReposForPlugin) 140 141 help := NewHelpAgent(fpa, fghc).GeneratePluginHelp() 142 if help == nil { 143 t.Fatal("HelpAgent returned nil Help struct pointer.") 144 } 145 if got, expected := sets.NewString(help.AllRepos...), sets.NewString(expectedAllRepos...); !got.Equal(expected) { 146 t.Errorf("Expected 'AllRepos' to be %q, but got %q.", expected.List(), got.List()) 147 } 148 checkPluginsForRepo := func(expected, got map[string][]string) { 149 for _, plugins := range expected { 150 sort.Strings(plugins) 151 } 152 for _, plugins := range got { 153 sort.Strings(plugins) 154 } 155 if !reflect.DeepEqual(expected, got) { 156 t.Errorf("Expected repo->plugin map %v, but got %v.", expected, got) 157 } 158 } 159 checkPluginsForRepo(normalExpectedPluginsForRepo, help.RepoPlugins) 160 checkPluginsForRepo(externalExpectedPluginsForRepo, help.RepoExternalPlugins) 161 162 checkPluginHelp := func(plugin string, expected, got pluginhelp.PluginHelp, eventsForPlugin []string) { 163 sort.Strings(eventsForPlugin) 164 sort.Strings(got.Events) 165 if expected, got := eventsForPlugin, got.Events; !reflect.DeepEqual(expected, got) { 166 t.Errorf("Expected plugin '%s' to subscribe to events %q, but got %q.", plugin, expected, got) 167 } 168 // Events field is correct, everything else should match the input exactly. 169 got.Events = nil 170 if !reflect.DeepEqual(got, expected) { 171 t.Errorf("Expected plugin '%s' to have help: %v, but got %v.", plugin, expected, got) 172 } 173 } 174 175 for plugin, expected := range normalHelp { 176 checkPluginHelp(plugin, expected, help.PluginHelp[plugin], normalExpectedEvents[plugin]) 177 } 178 checkPluginHelp("helpful-external", helpfulExternalHelp, help.ExternalPluginHelp["helpful-external"], externalExpectedEvents["helpful-external"]) 179 } 180 181 func registerNormalPlugins(t *testing.T, pluginsToEvents map[string][]string, pluginHelp map[string]pluginhelp.PluginHelp, expectedRepos map[string][]string) { 182 for plugin, events := range pluginsToEvents { 183 plugin := plugin 184 helpProvider := func(_ *plugins.Configuration, enabledRepos []string) (*pluginhelp.PluginHelp, error) { 185 if got, expected := sets.NewString(enabledRepos...), sets.NewString(expectedRepos[plugin]...); !got.Equal(expected) { 186 t.Errorf("Plugin '%s' expected to be enabled on repos %q, but got %q.", plugin, expected.List(), got.List()) 187 } 188 help := pluginHelp[plugin] 189 return &help, nil 190 } 191 for _, event := range events { 192 switch event { 193 case "issue_comment": 194 plugins.RegisterIssueCommentHandler(plugin, nil, helpProvider) 195 case "issue": 196 plugins.RegisterIssueHandler(plugin, nil, helpProvider) 197 case "pull_request": 198 plugins.RegisterPullRequestHandler(plugin, nil, helpProvider) 199 case "pull_request_review": 200 plugins.RegisterReviewEventHandler(plugin, nil, helpProvider) 201 case "pull_request_review_comment": 202 plugins.RegisterReviewCommentEventHandler(plugin, nil, helpProvider) 203 default: 204 t.Fatalf("Invalid test! Unknown event type '%s' for plugin '%s'.", event, plugin) 205 } 206 } 207 } 208 }