1+ package buildrun
2+
3+ import (
4+ "context"
5+ "fmt"
6+ "os"
7+ "path/filepath"
8+ "testing"
9+
10+ buildv1beta1 "github.com/shipwright-io/build/pkg/apis/build/v1beta1"
11+ shpfake "github.com/shipwright-io/build/pkg/client/clientset/versioned/fake"
12+ "github.com/shipwright-io/cli/pkg/shp/params"
13+ "github.com/spf13/cobra"
14+ corev1 "k8s.io/api/core/v1"
15+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
17+ "k8s.io/cli-runtime/pkg/genericclioptions"
18+ dynamicfake "k8s.io/client-go/dynamic/fake"
19+ "k8s.io/client-go/kubernetes/fake"
20+ "k8s.io/client-go/kubernetes/scheme"
21+ )
22+
23+ func TestGatherTaskRun (t * testing.T ) {
24+ name := "test-br-taskrun"
25+ namespace := "default"
26+ executorName := "test-tr"
27+ podName := "test-pod"
28+
29+ buildRun := & buildv1beta1.BuildRun {
30+ ObjectMeta : metav1.ObjectMeta {Name : name , Namespace : namespace },
31+ Status : buildv1beta1.BuildRunStatus {
32+ Executor : & buildv1beta1.BuildExecutor {Kind : "TaskRun" , Name : executorName },
33+ },
34+ }
35+
36+ taskRun := & unstructured.Unstructured {
37+ Object : map [string ]interface {} {
38+ "apiVersion" : "tekton.dev/v1" ,
39+ "kind" : "TaskRun" ,
40+ "metadata" : map [string ]interface {}{"name" : executorName , "namespace" : namespace },
41+ "status" : map [string ]interface {}{"podName" : podName },
42+ },
43+ }
44+
45+ pod := & corev1.Pod {
46+ ObjectMeta : metav1.ObjectMeta {
47+ Name : podName ,
48+ Namespace : namespace ,
49+ Labels : map [string ]string {"tekton.dev/taskRun" : executorName },
50+ },
51+ Spec : corev1.PodSpec {Containers : []corev1.Container {{Name : "step-build" }}},
52+ }
53+
54+ shpClient := shpfake .NewSimpleClientset (buildRun )
55+ kubeClient := fake .NewSimpleClientset (pod )
56+ dynamicClient := dynamicfake .NewSimpleDynamicClient (scheme .Scheme , taskRun )
57+
58+ tmpDir , _ := os .MkdirTemp ("" , "gather-tr-*" )
59+ defer os .RemoveAll (tmpDir )
60+
61+ p := params .NewParamsForTest (kubeClient , shpClient , dynamicClient , nil , namespace , nil , nil )
62+ ioStreams , _ , _ , _ := genericclioptions .NewTestIOStreams ()
63+ c := & cobra.Command {}
64+ c .SetContext (context .Background ())
65+ cmd := & GatherCommand {cmd : c , name : name , outputDir : tmpDir }
66+
67+ if err := cmd .Run (p , & ioStreams ); err != nil {
68+ t .Fatalf ("Gather.Run failed: %v" , err )
69+ }
70+
71+ expectedDir := filepath .Join (tmpDir , fmt .Sprintf ("buildrun-%s-gather" , name ))
72+ checkFiles (t , expectedDir , []string {"buildrun.yaml" , "taskrun.yaml" , "pod.yaml" , "logs/step-build.log" })
73+ }
74+
75+ func TestGatherPipelineRun (t * testing.T ) {
76+ name := "test-br-pipelinerun"
77+ namespace := "default"
78+ pipelineRunName := "test-pr"
79+ taskRunName := "test-pr-tr"
80+ podName := "test-pr-pod"
81+
82+ buildRun := & buildv1beta1.BuildRun {
83+ ObjectMeta : metav1.ObjectMeta {Name : name , Namespace : namespace },
84+ Status : buildv1beta1.BuildRunStatus {
85+ Executor : & buildv1beta1.BuildExecutor {Kind : "PipelineRun" , Name : pipelineRunName },
86+ },
87+ }
88+
89+ pipelineRun := & unstructured.Unstructured {
90+ Object : map [string ]interface {}{
91+ "apiVersion" : "tekton.dev/v1" ,
92+ "kind" : "PipelineRun" ,
93+ "metadata" : map [string ]interface {}{"name" : pipelineRunName , "namespace" : namespace },
94+ },
95+ }
96+
97+ taskRun := & unstructured.Unstructured {
98+ Object : map [string ]interface {}{
99+ "apiVersion" : "tekton.dev/v1" ,
100+ "kind" : "TaskRun" ,
101+ "metadata" : map [string ]interface {}{
102+ "name" : taskRunName ,
103+ "namespace" : namespace ,
104+ "labels" : map [string ]interface {}{"tekton.dev/pipelineRun" : pipelineRunName },
105+ },
106+ "status" : map [string ]interface {}{"podName" : podName },
107+ },
108+ }
109+
110+ pod := & corev1.Pod {
111+ ObjectMeta : metav1.ObjectMeta {
112+ Name : podName ,
113+ Namespace : namespace ,
114+ Labels : map [string ]string {"tekton.dev/taskRun" : taskRunName },
115+ },
116+ Spec : corev1.PodSpec {Containers : []corev1.Container {{Name : "step-build" }}},
117+ }
118+
119+ shpClient := shpfake .NewSimpleClientset (buildRun )
120+ kubeClient := fake .NewSimpleClientset (pod )
121+
122+ // Seed dynamic client with both PipelineRun and TaskRun
123+ dynamicClient := dynamicfake .NewSimpleDynamicClient (scheme .Scheme , pipelineRun , taskRun )
124+
125+ tmpDir , _ := os .MkdirTemp ("" , "gather-pr-*" )
126+ defer os .RemoveAll (tmpDir )
127+
128+ p := params .NewParamsForTest (kubeClient , shpClient , dynamicClient , nil , namespace , nil , nil )
129+ ioStreams , _ , _ , _ := genericclioptions .NewTestIOStreams ()
130+
131+ c := & cobra.Command {}
132+ c .SetContext (context .Background ())
133+ cmd := & GatherCommand {cmd : c , name : name , outputDir : tmpDir }
134+
135+
136+ if err := cmd .Run (p , & ioStreams ); err != nil {
137+ t .Fatalf ("Gather.Run failed: %v" , err )
138+ }
139+
140+ expectedDir := filepath .Join (tmpDir , fmt .Sprintf ("buildrun-%s-gather" , name ))
141+
142+
143+ // PipelineRun gather creates a slightly different directory structure
144+ checkFiles (t , expectedDir , []string {
145+ "buildrun.yaml" ,
146+ "pipelinerun.yaml" ,
147+ filepath .Join ("taskruns" , taskRunName + ".yaml" ),
148+ filepath .Join ("pods" , podName + ".yaml" ),
149+ filepath .Join ("logs" , taskRunName , "step-build.log" ),
150+ })
151+ }
152+
153+ func TestGatherArchive (t * testing.T ) {
154+ name := "test-br-archive"
155+ namespace := "default"
156+ executorName := "test-br"
157+
158+ buildRun := & buildv1beta1.BuildRun {
159+ ObjectMeta : metav1.ObjectMeta {Name : name , Namespace : namespace },
160+ Status : buildv1beta1.BuildRunStatus {
161+ Executor : & buildv1beta1.BuildExecutor {Kind : "TaskRun" , Name : executorName },
162+ },
163+ }
164+
165+ taskRun := & unstructured.Unstructured {
166+ Object : map [string ]interface {}{
167+ "apiVersion" : "tekton.dev/v1" ,
168+ "kind" : "TaskRun" ,
169+ "metadata" : map [string ]interface {}{"name" : executorName , "namespace" : namespace },
170+ "status" : map [string ]interface {}{"podName" : "some-pod" },
171+ },
172+ }
173+
174+ shpClient := shpfake .NewSimpleClientset (buildRun )
175+ kubeClient := fake .NewSimpleClientset () // Pod not strictly needed for archive logic test
176+ dynamicClient := dynamicfake .NewSimpleDynamicClient (scheme .Scheme , taskRun )
177+
178+ tmpDir , _ := os .MkdirTemp ("" , "gather-archive-*" )
179+ defer os .RemoveAll (tmpDir )
180+
181+ p := params .NewParamsForTest (kubeClient , shpClient , dynamicClient , nil , namespace , nil , nil )
182+ ioStreams , _ , _ , _ := genericclioptions .NewTestIOStreams ()
183+
184+ c := & cobra.Command {}
185+ c .SetContext (context .Background ())
186+
187+ // Enable the archive flag
188+ cmd := & GatherCommand {
189+ cmd : c ,
190+ name : name ,
191+ outputDir : tmpDir ,
192+ archive : true ,
193+ }
194+
195+ if err := cmd .Run (p , & ioStreams ); err != nil {
196+ t .Fatalf ("Gather.Run failed: %v" , err )
197+ }
198+
199+ expectedPrefix := filepath .Join (tmpDir , fmt .Sprintf ("buildrun-%s-gather" , name ))
200+ archivePath := expectedPrefix + ".tar.gz"
201+
202+ // Verify the archive file exists
203+ if _ , err := os .Stat (archivePath ); os .IsNotExist (err ) {
204+ t .Errorf ("expected archive file %q was not created" , archivePath )
205+ }
206+
207+ // Verify the temporary directory was cleaned up (deleted)
208+ if _ , err := os .Stat (expectedPrefix ); err == nil {
209+ t .Errorf ("expected directory %q to be deleted after archiving, but it still exists" , expectedPrefix )
210+ }
211+ }
212+
213+ func checkFiles (t * testing.T , baseDir string , files []string ) {
214+ for _ , f := range files {
215+ path := filepath .Join (baseDir , f )
216+ if _ , err := os .Stat (path ); os .IsNotExist (err ) {
217+ t .Errorf ("expected file %q not found in gathered directory" , path )
218+ }
219+ }
220+ }
0 commit comments