github.com/jenkins-x/jx/v2@v2.1.155/pkg/pipelinescheduler/testhelpers/helpers.go (about)

     1  package testhelpers
     2  
     3  import (
     4  	"io/ioutil"
     5  	"math/rand"
     6  	"path/filepath"
     7  	"testing"
     8  	"time"
     9  
    10  	v1 "github.com/jenkins-x/jx-api/pkg/apis/jenkins.io/v1"
    11  
    12  	"github.com/ghodss/yaml"
    13  
    14  	"github.com/jenkins-x/jx/v2/pkg/pipelinescheduler"
    15  	"github.com/jenkins-x/lighthouse/pkg/config"
    16  	"github.com/jenkins-x/lighthouse/pkg/plugins"
    17  
    18  	"github.com/stretchr/testify/assert"
    19  
    20  	"github.com/google/uuid"
    21  )
    22  
    23  // CompleteScheduler returns a SchedulerSpec completely filled with dummy data
    24  func CompleteScheduler() *v1.SchedulerSpec {
    25  	return &v1.SchedulerSpec{
    26  		Policy: pointerToGlobalProtectionPolicy(),
    27  		Merger: &v1.Merger{
    28  			ContextPolicy: &v1.ContextPolicy{
    29  				OptionalContexts:          PointerToReplaceableSliceOfStrings(),
    30  				RequiredContexts:          PointerToReplaceableSliceOfStrings(),
    31  				RequiredIfPresentContexts: PointerToReplaceableSliceOfStrings(),
    32  			},
    33  			MergeType:          pointerToUUID(),
    34  			TargetURL:          pointerToUUID(),
    35  			PRStatusBaseURL:    pointerToUUID(),
    36  			BlockerLabel:       pointerToUUID(),
    37  			SquashLabel:        pointerToUUID(),
    38  			MaxGoroutines:      pointerToRandomNumber(),
    39  			StatusUpdatePeriod: pointerToRandomDuration(),
    40  			SyncPeriod:         pointerToRandomDuration(),
    41  		},
    42  		Presubmits: &v1.Presubmits{
    43  			Items: []*v1.Presubmit{
    44  				{
    45  					MergeType: pointerToUUID(),
    46  					Context:   pointerToUUID(),
    47  					Report:    pointerToTrue(),
    48  					AlwaysRun: pointerToTrue(),
    49  					Optional:  pointerToTrue(),
    50  					ContextPolicy: &v1.RepoContextPolicy{
    51  						ContextPolicy: pointerToContextPolicy(),
    52  						Branches: &v1.ReplaceableMapOfStringContextPolicy{
    53  							Items: map[string]*v1.ContextPolicy{
    54  								uuid.New().String(): pointerToContextPolicy(),
    55  							},
    56  						},
    57  					},
    58  					Queries: []*v1.Query{{
    59  						Labels:                 PointerToReplaceableSliceOfStrings(),
    60  						ExcludedBranches:       PointerToReplaceableSliceOfStrings(),
    61  						IncludedBranches:       PointerToReplaceableSliceOfStrings(),
    62  						MissingLabels:          PointerToReplaceableSliceOfStrings(),
    63  						Milestone:              pointerToUUID(),
    64  						ReviewApprovedRequired: pointerToTrue(),
    65  					}},
    66  					Brancher:     pointerToBrancher(),
    67  					RerunCommand: pointerToUUID(),
    68  					Trigger:      pointerToUUID(),
    69  					Policy: &v1.ProtectionPolicies{
    70  						Items: map[string]*v1.ProtectionPolicy{
    71  							uuid.New().String(): pointerToProtectionPolicy(),
    72  						},
    73  					},
    74  					RegexpChangeMatcher: pointerToRegexpChangeMatcher(),
    75  					JobBase:             pointerToJobBase(),
    76  				},
    77  			},
    78  		},
    79  		Postsubmits: &v1.Postsubmits{
    80  			Items: []*v1.Postsubmit{
    81  				{
    82  					Report:              pointerToTrue(),
    83  					Context:             pointerToUUID(),
    84  					JobBase:             pointerToJobBase(),
    85  					RegexpChangeMatcher: pointerToRegexpChangeMatcher(),
    86  					Brancher:            pointerToBrancher(),
    87  				},
    88  			},
    89  		},
    90  		Trigger: &v1.Trigger{
    91  			IgnoreOkToTest: pointerToTrue(),
    92  			JoinOrgURL:     pointerToUUID(),
    93  			OnlyOrgMembers: pointerToTrue(),
    94  			TrustedOrg:     pointerToUUID(),
    95  		},
    96  		ScehdulerAgent: &v1.SchedulerAgent{
    97  			Agent: pointerToUUID(),
    98  		},
    99  		Approve: &v1.Approve{
   100  			RequireSelfApproval: pointerToTrue(),
   101  			LgtmActsAsApprove:   pointerToTrue(),
   102  			IssueRequired:       pointerToTrue(),
   103  			IgnoreReviewState:   pointerToTrue(),
   104  		},
   105  		ExternalPlugins: &v1.ReplaceableSliceOfExternalPlugins{
   106  			Items: []*v1.ExternalPlugin{
   107  				{
   108  					Name:     pointerToUUID(),
   109  					Events:   PointerToReplaceableSliceOfStrings(),
   110  					Endpoint: pointerToUUID(),
   111  				},
   112  			},
   113  		},
   114  		LGTM: &v1.Lgtm{
   115  			StoreTreeHash:    pointerToTrue(),
   116  			ReviewActsAsLgtm: pointerToTrue(),
   117  			StickyLgtmTeam:   pointerToUUID(),
   118  		},
   119  		Plugins: PointerToReplaceableSliceOfStrings(),
   120  	}
   121  }
   122  
   123  func pointerToTrue() *bool {
   124  	b := true
   125  	return &b
   126  }
   127  
   128  func pointerToUUID() *string {
   129  	s := uuid.New().String()
   130  	return &s
   131  }
   132  
   133  func pointerToRandomNumber() *int {
   134  	i := rand.Int() // #nosec
   135  	return &i
   136  }
   137  
   138  func pointerToRandomDuration() *time.Duration {
   139  	i := rand.Int63()
   140  	duration := time.Duration(i)
   141  	return &duration
   142  }
   143  
   144  // PointerToReplaceableSliceOfStrings creaters a ReplaceableSliceOfStrings and returns its pointer
   145  func PointerToReplaceableSliceOfStrings() *v1.ReplaceableSliceOfStrings {
   146  	return &v1.ReplaceableSliceOfStrings{
   147  		Items: []string{
   148  			uuid.New().String(),
   149  		},
   150  	}
   151  }
   152  
   153  // PointerToReplaceableMapOfStringString returns a ReplaceableMapOfStringString pointer
   154  func PointerToReplaceableMapOfStringString() *v1.ReplaceableMapOfStringString {
   155  	return &v1.ReplaceableMapOfStringString{
   156  		Items: map[string]string{
   157  			uuid.New().String(): uuid.New().String(),
   158  		},
   159  	}
   160  }
   161  
   162  func pointerToContextPolicy() *v1.ContextPolicy {
   163  	return &v1.ContextPolicy{
   164  		SkipUnknownContexts:       pointerToTrue(),
   165  		FromBranchProtection:      pointerToTrue(),
   166  		RequiredIfPresentContexts: PointerToReplaceableSliceOfStrings(),
   167  		RequiredContexts:          PointerToReplaceableSliceOfStrings(),
   168  		OptionalContexts:          PointerToReplaceableSliceOfStrings(),
   169  	}
   170  }
   171  
   172  func pointerToGlobalProtectionPolicy() *v1.GlobalProtectionPolicy {
   173  	return &v1.GlobalProtectionPolicy{
   174  		ProtectTested:    pointerToTrue(),
   175  		ProtectionPolicy: pointerToProtectionPolicy(),
   176  	}
   177  }
   178  
   179  func pointerToProtectionPolicy() *v1.ProtectionPolicy {
   180  	return &v1.ProtectionPolicy{
   181  		Restrictions: &v1.Restrictions{
   182  			Users: PointerToReplaceableSliceOfStrings(),
   183  			Teams: PointerToReplaceableSliceOfStrings(),
   184  		},
   185  		Admins: pointerToTrue(),
   186  		RequiredPullRequestReviews: &v1.ReviewPolicy{
   187  			DismissalRestrictions: &v1.Restrictions{
   188  				Users: PointerToReplaceableSliceOfStrings(),
   189  				Teams: PointerToReplaceableSliceOfStrings(),
   190  			},
   191  		},
   192  		RequiredStatusChecks: &v1.BranchProtectionContextPolicy{
   193  			Strict:   pointerToTrue(),
   194  			Contexts: PointerToReplaceableSliceOfStrings(),
   195  		},
   196  		Protect: pointerToTrue(),
   197  	}
   198  }
   199  
   200  func pointerToJobBase() *v1.JobBase {
   201  	return &v1.JobBase{
   202  		Labels:         PointerToReplaceableMapOfStringString(),
   203  		Namespace:      pointerToUUID(),
   204  		Cluster:        pointerToUUID(),
   205  		MaxConcurrency: pointerToRandomNumber(),
   206  		Agent:          pointerToUUID(),
   207  		Name:           pointerToUUID(),
   208  	}
   209  }
   210  
   211  func pointerToRegexpChangeMatcher() *v1.RegexpChangeMatcher {
   212  	return &v1.RegexpChangeMatcher{
   213  		RunIfChanged: pointerToUUID(),
   214  	}
   215  }
   216  
   217  func pointerToBrancher() *v1.Brancher {
   218  	return &v1.Brancher{
   219  		Branches:     PointerToReplaceableSliceOfStrings(),
   220  		SkipBranches: PointerToReplaceableSliceOfStrings(),
   221  	}
   222  }
   223  
   224  // SchedulerFile contains a list of leaf files to build the scheduler from
   225  type SchedulerFile struct {
   226  	// Filenames is the hierarchy with the leaf at the right
   227  	Filenames []string
   228  	Org       string
   229  	Repo      string
   230  }
   231  
   232  // BuildAndValidateProwConfig takes a list of schedulerFiles and builds them to a Prow config,
   233  // and validates them against the expectedConfigFilename and expectedPluginsFilename that make up the prow config.
   234  // Filepaths are relative to the baseDir
   235  func BuildAndValidateProwConfig(t *testing.T, baseDir string, expectedConfigFilename string,
   236  	expectedPluginsFilename string, schedulerFiles []SchedulerFile) {
   237  	var expectedConfig config.Config
   238  	if expectedConfigFilename != "" {
   239  		cfgBytes, err := ioutil.ReadFile(filepath.Join(baseDir, expectedConfigFilename))
   240  		assert.NoError(t, err)
   241  		err = yaml.Unmarshal(cfgBytes, &expectedConfig)
   242  		assert.NoError(t, err)
   243  	}
   244  
   245  	var expectedPlugins plugins.Configuration
   246  	if expectedPluginsFilename != "" {
   247  		bytes, err := ioutil.ReadFile(filepath.Join(baseDir, expectedPluginsFilename))
   248  		assert.NoError(t, err)
   249  		err = yaml.Unmarshal(bytes, &expectedPlugins)
   250  		assert.NoError(t, err)
   251  	}
   252  
   253  	schedulerLeaves := make([]*pipelinescheduler.SchedulerLeaf, 0)
   254  	for _, sfs := range schedulerFiles {
   255  		schedulers := make([]*v1.SchedulerSpec, 0)
   256  		for _, f := range sfs.Filenames {
   257  			bytes, err := ioutil.ReadFile(filepath.Join(baseDir, f))
   258  			assert.NoError(t, err)
   259  			s := v1.SchedulerSpec{}
   260  			err = yaml.Unmarshal(bytes, &s)
   261  			assert.NoError(t, err)
   262  			schedulers = append(schedulers, &s)
   263  		}
   264  		s, err := pipelinescheduler.Build(schedulers)
   265  		assert.NoError(t, err)
   266  		schedulerLeaves = append(schedulerLeaves, &pipelinescheduler.SchedulerLeaf{
   267  			Repo:          sfs.Repo,
   268  			Org:           sfs.Org,
   269  			SchedulerSpec: s,
   270  		})
   271  	}
   272  
   273  	cfg, plugs, err := pipelinescheduler.BuildProwConfig(schedulerLeaves)
   274  	assert.NoError(t, err)
   275  	if expectedConfigFilename != "" {
   276  		expected, err := yaml.Marshal(&expectedConfig)
   277  		assert.NoError(t, err)
   278  		actual, err := yaml.Marshal(cfg)
   279  		assert.NoError(t, err)
   280  		assert.NotNil(t, expected)
   281  		assert.Equal(t, string(expected), string(actual))
   282  	}
   283  	if expectedPluginsFilename != "" {
   284  		expected, err := yaml.Marshal(&expectedPlugins)
   285  		assert.NoError(t, err)
   286  		actual, err := yaml.Marshal(plugs)
   287  		assert.NoError(t, err)
   288  		assert.Equal(t, string(expected), string(actual))
   289  	}
   290  }