Added unit test cases for webhook
This commit is contained in:
		
							parent
							
								
									90b685db9b
								
							
						
					
					
						commit
						b11ca32d1a
					
				|  | @ -79,6 +79,7 @@ func (in *Jenkins) ValidateDelete() error { | ||||||
| type PluginDataManager struct { | type PluginDataManager struct { | ||||||
| 	PluginDataCache    PluginsInfo | 	PluginDataCache    PluginsInfo | ||||||
| 	Hosturl            string | 	Hosturl            string | ||||||
|  | 	Timeout            time.Duration | ||||||
| 	CompressedFilePath string | 	CompressedFilePath string | ||||||
| 	PluginDataFile     string | 	PluginDataFile     string | ||||||
| 	IsCached           bool | 	IsCached           bool | ||||||
|  | @ -160,9 +161,9 @@ func Validate(r Jenkins) error { | ||||||
| 
 | 
 | ||||||
| 			if hasVulnerabilities { | 			if hasVulnerabilities { | ||||||
| 				if pluginData.Kind == "base" { | 				if pluginData.Kind == "base" { | ||||||
| 					faultyBasePlugins += plugin.Name + ":" + pluginData.Version + "\n" | 					faultyBasePlugins += "\n" + plugin.Name + ":" + pluginData.Version | ||||||
| 				} else { | 				} else { | ||||||
| 					faultyUserPlugins += plugin.Name + ":" + pluginData.Version + "\n" | 					faultyUserPlugins += "\n" + plugin.Name + ":" + pluginData.Version | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | @ -170,10 +171,10 @@ func Validate(r Jenkins) error { | ||||||
| 	if len(faultyBasePlugins) > 0 || len(faultyUserPlugins) > 0 { | 	if len(faultyBasePlugins) > 0 || len(faultyUserPlugins) > 0 { | ||||||
| 		var errormsg string | 		var errormsg string | ||||||
| 		if len(faultyBasePlugins) > 0 { | 		if len(faultyBasePlugins) > 0 { | ||||||
| 			errormsg += "Security vulnerabilities detected in the following base plugins: \n" + faultyBasePlugins | 			errormsg += "security vulnerabilities detected in the following base plugins: " + faultyBasePlugins | ||||||
| 		} | 		} | ||||||
| 		if len(faultyUserPlugins) > 0 { | 		if len(faultyUserPlugins) > 0 { | ||||||
| 			errormsg += "Security vulnerabilities detected in the following user-defined plugins: \n" + faultyUserPlugins | 			errormsg += "security vulnerabilities detected in the following user-defined plugins: " + faultyUserPlugins | ||||||
| 		} | 		} | ||||||
| 		return errors.New(errormsg) | 		return errors.New(errormsg) | ||||||
| 	} | 	} | ||||||
|  | @ -188,6 +189,7 @@ func NewPluginsDataManager() *PluginDataManager { | ||||||
| 		PluginDataFile:     "/tmp/plugins.json", | 		PluginDataFile:     "/tmp/plugins.json", | ||||||
| 		IsCached:           false, | 		IsCached:           false, | ||||||
| 		Attempts:           0, | 		Attempts:           0, | ||||||
|  | 		Timeout:            time.Duration(1000) * time.Second, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -256,7 +258,7 @@ func (in *PluginDataManager) download() error { | ||||||
| 	defer out.Close() | 	defer out.Close() | ||||||
| 
 | 
 | ||||||
| 	client := http.Client{ | 	client := http.Client{ | ||||||
| 		Timeout: 1000 * time.Second, | 		Timeout: in.Timeout, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	resp, err := client.Get(in.Hosturl) | 	resp, err := client.Get(in.Hosturl) | ||||||
|  | @ -314,9 +316,11 @@ func (in *PluginDataManager) cache() error { | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // returns a semantic version that can be used for comparison
 | // returns a semantic version that can be used for comparison, allowed versioning format vMAJOR.MINOR.PATCH or MAJOR.MINOR.PATCH
 | ||||||
| func makeSemanticVersion(version string) string { | func makeSemanticVersion(version string) string { | ||||||
| 	version = "v" + version | 	if version[0] != 'v' { | ||||||
|  | 		version = "v" + version | ||||||
|  | 	} | ||||||
| 	return semver.Canonical(version) | 	return semver.Canonical(version) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,163 @@ | ||||||
|  | package v1alpha2 | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  | 	"testing" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/jenkinsci/kubernetes-operator/pkg/constants" | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | 	corev1 "k8s.io/api/core/v1" | ||||||
|  | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestMakeSemanticVersion(t *testing.T) { | ||||||
|  | 	t.Run("only major version specified", func(t *testing.T) { | ||||||
|  | 		got := makeSemanticVersion("1") | ||||||
|  | 		assert.Equal(t, got, "v1.0.0") | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("major and minor version specified", func(t *testing.T) { | ||||||
|  | 		got := makeSemanticVersion("1.2") | ||||||
|  | 		assert.Equal(t, got, "v1.2.0") | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("major,minor and patch version specified", func(t *testing.T) { | ||||||
|  | 		got := makeSemanticVersion("1.2.3") | ||||||
|  | 		assert.Equal(t, got, "v1.2.3") | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("semantic versions begin with a leading v and no patch version", func(t *testing.T) { | ||||||
|  | 		got := makeSemanticVersion("v2.5") | ||||||
|  | 		assert.Equal(t, got, "v2.5.0") | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("semantic versions with prerelease versions", func(t *testing.T) { | ||||||
|  | 		got := makeSemanticVersion("2.1.2-alpha.1") | ||||||
|  | 		assert.Equal(t, got, "v2.1.2-alpha.1") | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("semantic versions with prerelease versions", func(t *testing.T) { | ||||||
|  | 		got := makeSemanticVersion("0.11.2-9.c8b45b8bb173") | ||||||
|  | 		assert.Equal(t, got, "v0.11.2-9.c8b45b8bb173") | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("semantic versions with build suffix", func(t *testing.T) { | ||||||
|  | 		got := makeSemanticVersion("1.7.9+meta") | ||||||
|  | 		assert.Equal(t, got, "v1.7.9") | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("invalid semantic version", func(t *testing.T) { | ||||||
|  | 		got := makeSemanticVersion("google-login-1.2") | ||||||
|  | 		assert.Equal(t, got, "") | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestCompareVersions(t *testing.T) { | ||||||
|  | 	t.Run("Plugin Version lies between first and last version", func(t *testing.T) { | ||||||
|  | 		got := compareVersions("1.2", "1.6", "1.4") | ||||||
|  | 		assert.Equal(t, got, true) | ||||||
|  | 	}) | ||||||
|  | 	t.Run("Plugin Version is greater than the last version", func(t *testing.T) { | ||||||
|  | 		got := compareVersions("1", "2", "3") | ||||||
|  | 		assert.Equal(t, got, false) | ||||||
|  | 	}) | ||||||
|  | 	t.Run("Plugin Version is less than the first version", func(t *testing.T) { | ||||||
|  | 		got := compareVersions("1.4", "2.5", "1.1") | ||||||
|  | 		assert.Equal(t, got, false) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("Plugins Versions have prerelease version and it lies between first and last version", func(t *testing.T) { | ||||||
|  | 		got := compareVersions("1.2.1-alpha", "1.2.1", "1.2.1-beta") | ||||||
|  | 		assert.Equal(t, got, true) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("Plugins Versions have prerelease version and it is greater than the last version", func(t *testing.T) { | ||||||
|  | 		got := compareVersions("v2.2.1-alpha", "v2.5.1-beta.1", "v2.5.1-beta.2") | ||||||
|  | 		assert.Equal(t, got, false) | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestValidate(t *testing.T) { | ||||||
|  | 	t.Run("Validating when plugins data file is not fetched", func(t *testing.T) { | ||||||
|  | 		userplugins := []Plugin{{Name: "script-security", Version: "1.77"}, {Name: "git-client", Version: "3.9"}, {Name: "git", Version: "4.8.1"}, {Name: "plain-credentials", Version: "1.7"}} | ||||||
|  | 		jenkinscr := *createJenkinsCR(userplugins, true) | ||||||
|  | 		got := jenkinscr.ValidateCreate() | ||||||
|  | 		assert.Equal(t, got, errors.New("plugins data has not been fetched")) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	isInitialized := make(chan bool) | ||||||
|  | 	go PluginsMgr.FetchPluginData(isInitialized) | ||||||
|  | 	if <-isInitialized { | ||||||
|  | 		t.Run("Validating a Jenkins CR with plugins not having security warnings and validation is turned on", func(t *testing.T) { | ||||||
|  | 			userplugins := []Plugin{{Name: "script-security", Version: "1.77"}, {Name: "git-client", Version: "3.9"}, {Name: "git", Version: "4.8.1"}, {Name: "plain-credentials", Version: "1.7"}} | ||||||
|  | 			jenkinscr := *createJenkinsCR(userplugins, true) | ||||||
|  | 			got := jenkinscr.ValidateCreate() | ||||||
|  | 			assert.Nil(t, got) | ||||||
|  | 		}) | ||||||
|  | 
 | ||||||
|  | 		t.Run("Validating a Jenkins CR with some of the plugins having security warnings and validation is turned on", func(t *testing.T) { | ||||||
|  | 			userplugins := []Plugin{{Name: "google-login", Version: "1.2"}, {Name: "mailer", Version: "1.1"}, {Name: "git", Version: "4.8.1"}, {Name: "command-launcher", Version: "1.6"}, {Name: "workflow-cps", Version: "2.59"}} | ||||||
|  | 			jenkinscr := *createJenkinsCR(userplugins, true) | ||||||
|  | 			got := jenkinscr.ValidateCreate() | ||||||
|  | 			assert.Equal(t, got, errors.New("security vulnerabilities detected in the following user-defined plugins: \nworkflow-cps:2.59\ngoogle-login:1.2\nmailer:1.1")) | ||||||
|  | 		}) | ||||||
|  | 
 | ||||||
|  | 		t.Run("Updating a Jenkins CR with some of the plugins having security warnings and validation is turned on", func(t *testing.T) { | ||||||
|  | 			userplugins := []Plugin{{Name: "google-login", Version: "1.2"}, {Name: "mailer", Version: "1.1"}, {Name: "git", Version: "4.8.1"}, {Name: "command-launcher", Version: "1.6"}, {Name: "workflow-cps", Version: "2.59"}} | ||||||
|  | 			oldjenkinscr := *createJenkinsCR(userplugins, true) | ||||||
|  | 
 | ||||||
|  | 			userplugins = []Plugin{{Name: "handy-uri-templates-2-api", Version: "2.1.8-1.0"}, {Name: "resource-disposer", Version: "0.8"}, {Name: "jjwt-api", Version: "0.11.2-9.c8b45b8bb173"}, {Name: "blueocean-github-pipeline", Version: "1.2.0-beta-3"}, {Name: "ghprb", Version: "1.39"}} | ||||||
|  | 			newjenkinscr := *createJenkinsCR(userplugins, true) | ||||||
|  | 			got := newjenkinscr.ValidateUpdate(&oldjenkinscr) | ||||||
|  | 			assert.Equal(t, got, errors.New("security vulnerabilities detected in the following user-defined plugins: \nresource-disposer:0.8\nblueocean-github-pipeline:1.2.0-beta-3\nghprb:1.39")) | ||||||
|  | 		}) | ||||||
|  | 
 | ||||||
|  | 		t.Run("Validation is turned off", func(t *testing.T) { | ||||||
|  | 			userplugins := []Plugin{{Name: "google-login", Version: "1.2"}, {Name: "mailer", Version: "1.1"}, {Name: "git", Version: "4.8.1"}, {Name: "command-launcher", Version: "1.6"}, {Name: "workflow-cps", Version: "2.59"}} | ||||||
|  | 			jenkinscr := *createJenkinsCR(userplugins, false) | ||||||
|  | 			got := jenkinscr.ValidateCreate() | ||||||
|  | 			assert.Nil(t, got) | ||||||
|  | 		}) | ||||||
|  | 	} else { | ||||||
|  | 		t.Fatal("Plugin Data File is not Downloaded") | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestFetchPluginData(t *testing.T) { | ||||||
|  | 	t.Run("Timeout error while downloading plugins data file", func(t *testing.T) { | ||||||
|  | 		pluginsDataMgr := *NewPluginsDataManager() | ||||||
|  | 		pluginsDataMgr.Timeout = time.Duration(1) * time.Nanosecond | ||||||
|  | 		got := pluginsDataMgr.download() | ||||||
|  | 		assert.NotNil(t, got) | ||||||
|  | 	}) | ||||||
|  | 	t.Run("Successfully fetching plugins data file", func(t *testing.T) { | ||||||
|  | 		isInitialized := make(chan bool) | ||||||
|  | 		pluginsDataMgr := *NewPluginsDataManager() | ||||||
|  | 		go pluginsDataMgr.FetchPluginData(isInitialized) | ||||||
|  | 		assert.Equal(t, <-isInitialized, true) | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func createJenkinsCR(userPlugins []Plugin, validateSecurityWarnings bool) *Jenkins { | ||||||
|  | 	jenkins := &Jenkins{ | ||||||
|  | 		TypeMeta: JenkinsTypeMeta(), | ||||||
|  | 		ObjectMeta: metav1.ObjectMeta{ | ||||||
|  | 			Name:      "Jenkins", | ||||||
|  | 			Namespace: "test", | ||||||
|  | 		}, | ||||||
|  | 		Spec: JenkinsSpec{ | ||||||
|  | 			Master: JenkinsMaster{ | ||||||
|  | 				Annotations: map[string]string{"test": "label"}, | ||||||
|  | 				Plugins:     userPlugins, | ||||||
|  | 			}, | ||||||
|  | 			ValidateSecurityWarnings: validateSecurityWarnings, | ||||||
|  | 			Service: Service{ | ||||||
|  | 				Type: corev1.ServiceTypeNodePort, | ||||||
|  | 				Port: constants.DefaultHTTPPortInt32, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return jenkins | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue