github.com/jenkins-x/jx/v2@v2.1.155/pkg/tekton/pipelines_test.go (about)

     1  // +build unit
     2  
     3  package tekton_test
     4  
     5  import (
     6  	"path"
     7  	"strings"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/google/go-cmp/cmp"
    12  	v1 "github.com/jenkins-x/jx-api/pkg/apis/jenkins.io/v1"
    13  	jxfake "github.com/jenkins-x/jx-api/pkg/client/clientset/versioned/fake"
    14  	"github.com/jenkins-x/jx/v2/pkg/cmd/clients/fake"
    15  	"github.com/jenkins-x/jx/v2/pkg/cmd/opts"
    16  	"github.com/jenkins-x/jx/v2/pkg/cmd/testhelpers"
    17  	"github.com/jenkins-x/jx/v2/pkg/gits"
    18  	"github.com/jenkins-x/jx/v2/pkg/tekton"
    19  	"github.com/jenkins-x/jx/v2/pkg/tekton/syntax"
    20  	"github.com/jenkins-x/jx/v2/pkg/tekton/tekton_helpers_test"
    21  	"github.com/stretchr/testify/assert"
    22  	"github.com/tektoncd/pipeline/pkg/apis/pipeline"
    23  	"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1"
    24  	tektonv1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
    25  	corev1 "k8s.io/api/core/v1"
    26  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  )
    28  
    29  const (
    30  	ns = "jx"
    31  )
    32  
    33  func TestPipelineRunIsNotPendingCompletedRun(t *testing.T) {
    34  	now := metav1.Now()
    35  	pr := &v1alpha1.PipelineRun{
    36  		ObjectMeta: metav1.ObjectMeta{
    37  			Name:      "PR1",
    38  			Namespace: ns,
    39  			Labels: map[string]string{
    40  				tekton.LabelRepo:    "fakerepo",
    41  				tekton.LabelBranch:  "fakebranch",
    42  				tekton.LabelOwner:   "fakeowner",
    43  				tekton.LabelContext: "fakecontext",
    44  			},
    45  		},
    46  		Spec: v1alpha1.PipelineRunSpec{
    47  			Params: []v1alpha1.Param{
    48  				{
    49  					Name:  "version",
    50  					Value: syntax.StringParamValue("v1"),
    51  				},
    52  				{
    53  					Name:  "build_id",
    54  					Value: syntax.StringParamValue("1"),
    55  				},
    56  			},
    57  		},
    58  		Status: v1alpha1.PipelineRunStatus{
    59  			PipelineRunStatusFields: tektonv1beta1.PipelineRunStatusFields{
    60  				CompletionTime: &now,
    61  			},
    62  		},
    63  	}
    64  
    65  	assert.True(t, tekton.PipelineRunIsNotPending(pr))
    66  }
    67  
    68  func TestPipelineRunIsNotPendingRunningSteps(t *testing.T) {
    69  	taskRunStatusMap := make(map[string]*v1alpha1.PipelineRunTaskRunStatus)
    70  	taskRunStatusMap["faketaskrun"] = &v1alpha1.PipelineRunTaskRunStatus{
    71  		Status: &v1alpha1.TaskRunStatus{
    72  			TaskRunStatusFields: tektonv1beta1.TaskRunStatusFields{
    73  				Steps: []v1alpha1.StepState{{
    74  					ContainerState: corev1.ContainerState{
    75  						Running: &corev1.ContainerStateRunning{},
    76  					},
    77  				}},
    78  			},
    79  		},
    80  	}
    81  
    82  	pr := &v1alpha1.PipelineRun{
    83  		ObjectMeta: metav1.ObjectMeta{
    84  			Name:      "PR1",
    85  			Namespace: ns,
    86  			Labels: map[string]string{
    87  				tekton.LabelRepo:    "fakerepo",
    88  				tekton.LabelBranch:  "fakebranch",
    89  				tekton.LabelOwner:   "fakeowner",
    90  				tekton.LabelContext: "fakecontext",
    91  			},
    92  		},
    93  		Spec: v1alpha1.PipelineRunSpec{
    94  			Params: []v1alpha1.Param{
    95  				{Name: "version", Value: syntax.StringParamValue("v1")},
    96  				{Name: "build_id", Value: syntax.StringParamValue("1")},
    97  			},
    98  		},
    99  		Status: v1alpha1.PipelineRunStatus{
   100  			PipelineRunStatusFields: tektonv1beta1.PipelineRunStatusFields{
   101  				TaskRuns: taskRunStatusMap,
   102  			},
   103  		},
   104  	}
   105  
   106  	assert.True(t, tekton.PipelineRunIsNotPending(pr))
   107  }
   108  
   109  func TestPipelineRunIsNotPendingWaitingSteps(t *testing.T) {
   110  	taskRunStatusMap := make(map[string]*v1alpha1.PipelineRunTaskRunStatus)
   111  	taskRunStatusMap["faketaskrun"] = &v1alpha1.PipelineRunTaskRunStatus{
   112  		Status: &v1alpha1.TaskRunStatus{
   113  			TaskRunStatusFields: tektonv1beta1.TaskRunStatusFields{
   114  				Steps: []v1alpha1.StepState{{
   115  					ContainerState: corev1.ContainerState{
   116  						Waiting: &corev1.ContainerStateWaiting{
   117  							Message: "Pending",
   118  						},
   119  					},
   120  				}},
   121  			},
   122  		},
   123  	}
   124  
   125  	pr := &v1alpha1.PipelineRun{
   126  		ObjectMeta: metav1.ObjectMeta{
   127  			Name:      "PR1",
   128  			Namespace: ns,
   129  			Labels: map[string]string{
   130  				tekton.LabelRepo:    "fakerepo",
   131  				tekton.LabelBranch:  "fakebranch",
   132  				tekton.LabelOwner:   "fakeowner",
   133  				tekton.LabelContext: "fakecontext",
   134  			},
   135  		},
   136  		Spec: v1alpha1.PipelineRunSpec{
   137  			Params: []v1alpha1.Param{
   138  				{Name: "version", Value: syntax.StringParamValue("v1")},
   139  				{Name: "build_id", Value: syntax.StringParamValue("1")},
   140  			},
   141  		},
   142  		Status: v1alpha1.PipelineRunStatus{
   143  			PipelineRunStatusFields: tektonv1beta1.PipelineRunStatusFields{
   144  				TaskRuns: taskRunStatusMap,
   145  			},
   146  		},
   147  	}
   148  
   149  	assert.False(t, tekton.PipelineRunIsNotPending(pr))
   150  }
   151  
   152  func TestPipelineRunIsNotPendingWaitingStepsInPodInitializing(t *testing.T) {
   153  	taskRunStatusMap := make(map[string]*v1alpha1.PipelineRunTaskRunStatus)
   154  	taskRunStatusMap["faketaskrun"] = &v1alpha1.PipelineRunTaskRunStatus{
   155  		Status: &v1alpha1.TaskRunStatus{
   156  			TaskRunStatusFields: tektonv1beta1.TaskRunStatusFields{
   157  				Steps: []v1alpha1.StepState{{
   158  					ContainerState: corev1.ContainerState{
   159  						Waiting: &corev1.ContainerStateWaiting{
   160  							Reason: "PodInitializing",
   161  						},
   162  					},
   163  				}},
   164  			},
   165  		},
   166  	}
   167  
   168  	pr := &v1alpha1.PipelineRun{
   169  		ObjectMeta: metav1.ObjectMeta{
   170  			Name:      "PR1",
   171  			Namespace: ns,
   172  			Labels: map[string]string{
   173  				tekton.LabelRepo:    "fakerepo",
   174  				tekton.LabelBranch:  "fakebranch",
   175  				tekton.LabelOwner:   "fakeowner",
   176  				tekton.LabelContext: "fakecontext",
   177  			},
   178  		},
   179  		Spec: v1alpha1.PipelineRunSpec{
   180  			Params: []v1alpha1.Param{
   181  				{Name: "version", Value: syntax.StringParamValue("v1")},
   182  				{Name: "build_id", Value: syntax.StringParamValue("1")},
   183  			},
   184  		},
   185  		Status: v1alpha1.PipelineRunStatus{
   186  			PipelineRunStatusFields: tektonv1beta1.PipelineRunStatusFields{
   187  				TaskRuns: taskRunStatusMap,
   188  			},
   189  		},
   190  	}
   191  
   192  	assert.True(t, tekton.PipelineRunIsNotPending(pr))
   193  }
   194  
   195  func TestGenerateNextBuildNumber(t *testing.T) {
   196  	testCases := []struct {
   197  		name                string
   198  		expectedBuildNumber string
   199  	}{{
   200  		name:                "valid",
   201  		expectedBuildNumber: "309",
   202  	},
   203  		{
   204  			name:                "no_activities",
   205  			expectedBuildNumber: "1",
   206  		},
   207  		{
   208  			name:                "unparseable_build_number",
   209  			expectedBuildNumber: "308",
   210  		}}
   211  
   212  	for _, tt := range testCases {
   213  		t.Run(tt.name, func(t *testing.T) {
   214  			testCaseDir := path.Join("test_data", "next_build_number", tt.name)
   215  
   216  			activities := tekton_helpers_test.AssertLoadPipelineActivities(t, testCaseDir)
   217  
   218  			commonOpts := opts.NewCommonOptionsWithFactory(fake.NewFakeFactory())
   219  			options := &commonOpts
   220  			testhelpers.ConfigureTestOptions(options, options.Git(), options.Helm())
   221  
   222  			tektonClient, ns, err := options.TektonClient()
   223  			assert.NoError(t, err, "There shouldn't be any error getting the fake Tekton Client")
   224  
   225  			jxClient := jxfake.NewSimpleClientset(activities)
   226  
   227  			repo := &gits.GitRepository{
   228  				Name:         "jx",
   229  				Host:         "github.com",
   230  				Organisation: "jenkins-x",
   231  			}
   232  			nextBuildNumber, err := tekton.GenerateNextBuildNumber(tektonClient, jxClient, ns, repo, "master", 30*time.Second, "release", true)
   233  			assert.NoError(t, err, "There shouldn't be an error getting the next build number")
   234  			assert.Equal(t, tt.expectedBuildNumber, nextBuildNumber)
   235  		})
   236  	}
   237  }
   238  
   239  func TestStructureForPipelineRun(t *testing.T) {
   240  	pipelineName := "some-pipeline-1"
   241  	unrelatedSuffix := "-not-related"
   242  
   243  	existingStructure := &v1.PipelineStructure{
   244  		ObjectMeta: metav1.ObjectMeta{
   245  			Name:      pipelineName,
   246  			Namespace: ns,
   247  		},
   248  	}
   249  
   250  	originalRun := &v1alpha1.PipelineRun{
   251  		ObjectMeta: metav1.ObjectMeta{
   252  			Name:      pipelineName,
   253  			Namespace: ns,
   254  			Labels: map[string]string{
   255  				pipeline.GroupName + pipeline.PipelineLabelKey: pipelineName,
   256  			},
   257  		},
   258  		Spec: v1alpha1.PipelineRunSpec{
   259  			PipelineRef: &v1alpha1.PipelineRef{
   260  				Name: pipelineName,
   261  			},
   262  		},
   263  	}
   264  
   265  	secondRun := &v1alpha1.PipelineRun{
   266  		ObjectMeta: metav1.ObjectMeta{
   267  			Name:      pipelineName + "-a1b2c",
   268  			Namespace: ns,
   269  			Labels: map[string]string{
   270  				pipeline.GroupName + pipeline.PipelineLabelKey: pipelineName,
   271  			},
   272  		},
   273  		Spec: v1alpha1.PipelineRunSpec{
   274  			PipelineRef: &v1alpha1.PipelineRef{
   275  				Name: pipelineName,
   276  			},
   277  		},
   278  	}
   279  
   280  	unrelatedRun := &v1alpha1.PipelineRun{
   281  		ObjectMeta: metav1.ObjectMeta{
   282  			Name:      pipelineName + unrelatedSuffix,
   283  			Namespace: ns,
   284  			Labels: map[string]string{
   285  				pipeline.GroupName + pipeline.PipelineLabelKey: pipelineName + unrelatedSuffix,
   286  			},
   287  		},
   288  		Spec: v1alpha1.PipelineRunSpec{
   289  			PipelineRef: &v1alpha1.PipelineRef{
   290  				Name: pipelineName + unrelatedSuffix,
   291  			},
   292  		},
   293  	}
   294  
   295  	jxClient := jxfake.NewSimpleClientset(existingStructure)
   296  
   297  	forOriginal, err := tekton.StructureForPipelineRun(jxClient, ns, originalRun)
   298  	assert.NoError(t, err)
   299  	if d := cmp.Diff(existingStructure, forOriginal); d != "" {
   300  		t.Errorf("Generated PipelineStructure for original PipelineRun did not match expected: %s", d)
   301  	}
   302  
   303  	forSecondRun, err := tekton.StructureForPipelineRun(jxClient, ns, secondRun)
   304  	assert.NoError(t, err)
   305  	if d := cmp.Diff(existingStructure, forSecondRun); d != "" {
   306  		t.Errorf("Generated PipelineStructure for second run PipelineRun did not match expected: %s", d)
   307  	}
   308  
   309  	_, err = tekton.StructureForPipelineRun(jxClient, ns, unrelatedRun)
   310  	assert.NotNil(t, err)
   311  	assert.True(t, strings.Contains(err.Error(), "pipelinestructures.jenkins.io \""+pipelineName+unrelatedSuffix+"\" not found"))
   312  }