github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/controllers/core/extension/reconciler_test.go (about)

     1  package extension
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     8  	"k8s.io/apimachinery/pkg/types"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  
    13  	"github.com/tilt-dev/wmclient/pkg/analytics"
    14  
    15  	tiltanalytics "github.com/tilt-dev/tilt/internal/analytics"
    16  	"github.com/tilt-dev/tilt/internal/controllers/fake"
    17  	"github.com/tilt-dev/tilt/internal/testutils/tempdir"
    18  	"github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1"
    19  )
    20  
    21  func TestDefault(t *testing.T) {
    22  	f := newFixture(t)
    23  	repo := f.setupRepo()
    24  
    25  	ext := v1alpha1.Extension{
    26  		ObjectMeta: metav1.ObjectMeta{
    27  			Name: "my-repo:my-ext",
    28  		},
    29  		Spec: v1alpha1.ExtensionSpec{
    30  			RepoName: "my-repo",
    31  			RepoPath: "my-ext",
    32  			Args:     []string{"--namespaces=foo"},
    33  		},
    34  	}
    35  	f.Create(&ext)
    36  
    37  	f.MustGet(types.NamespacedName{Name: "my-repo:my-ext"}, &ext)
    38  
    39  	p := f.JoinPath("my-repo", "my-ext", "Tiltfile")
    40  	require.Equal(t, p, ext.Status.Path)
    41  
    42  	var tf v1alpha1.Tiltfile
    43  	f.MustGet(types.NamespacedName{Name: "my-repo:my-ext"}, &tf)
    44  	require.Equal(t, tf.Spec, v1alpha1.TiltfileSpec{
    45  		Path:      p,
    46  		Labels:    map[string]string{"extension.my-repo_my-ext": "extension.my-repo_my-ext"},
    47  		RestartOn: &v1alpha1.RestartOnSpec{FileWatches: []string{"configs:my-repo:my-ext"}},
    48  		Args:      []string{"--namespaces=foo"},
    49  	})
    50  
    51  	assert.Equal(t, f.ma.Counts, []analytics.CountEvent{
    52  		analytics.CountEvent{
    53  			Name: "api.extension.load",
    54  			Tags: map[string]string{
    55  				"ext_path":      "my-ext",
    56  				"repo_type":     "file",
    57  				"repo_url_hash": tiltanalytics.HashSHA1(repo.Spec.URL),
    58  			},
    59  			N: 1,
    60  		},
    61  	})
    62  }
    63  
    64  func TestCleanupTiltfile(t *testing.T) {
    65  	f := newFixture(t)
    66  	f.setupRepo()
    67  
    68  	ext := v1alpha1.Extension{
    69  		ObjectMeta: metav1.ObjectMeta{
    70  			Name: "my-repo:my-ext",
    71  		},
    72  		Spec: v1alpha1.ExtensionSpec{
    73  			RepoName: "my-repo",
    74  			RepoPath: "my-ext",
    75  		},
    76  	}
    77  	f.Create(&ext)
    78  
    79  	f.MustGet(types.NamespacedName{Name: "my-repo:my-ext"}, &ext)
    80  
    81  	p := f.JoinPath("my-repo", "my-ext", "Tiltfile")
    82  
    83  	var tf v1alpha1.Tiltfile
    84  	f.MustGet(types.NamespacedName{Name: "my-repo:my-ext"}, &tf)
    85  	require.Equal(t, p, tf.Spec.Path)
    86  
    87  	f.Delete(&ext)
    88  	assert.False(t, f.Get(types.NamespacedName{Name: "my-repo:my-ext"}, &tf))
    89  }
    90  
    91  func TestMissing(t *testing.T) {
    92  	f := newFixture(t)
    93  	f.setupRepo()
    94  
    95  	ext := v1alpha1.Extension{
    96  		ObjectMeta: metav1.ObjectMeta{
    97  			Name: "my-repo:my-ext",
    98  		},
    99  		Spec: v1alpha1.ExtensionSpec{
   100  			RepoName: "my-repo",
   101  			RepoPath: "my-ext2",
   102  		},
   103  	}
   104  	f.Create(&ext)
   105  
   106  	f.MustGet(types.NamespacedName{Name: "my-repo:my-ext"}, &ext)
   107  	p := f.JoinPath("my-repo", "my-ext2", "Tiltfile")
   108  	require.Equal(t, ext.Status.Error,
   109  		fmt.Sprintf("no extension tiltfile found at %s", p), ext.Status.Error)
   110  }
   111  
   112  // Verify that args are propagated to the tiltfile when changed.
   113  func TestChangeArgs(t *testing.T) {
   114  	f := newFixture(t)
   115  	f.setupRepo()
   116  
   117  	ext := v1alpha1.Extension{
   118  		ObjectMeta: metav1.ObjectMeta{
   119  			Name: "ext",
   120  		},
   121  		Spec: v1alpha1.ExtensionSpec{
   122  			RepoName: "my-repo",
   123  			RepoPath: "my-ext",
   124  			Args:     []string{"--namespace=bar"},
   125  		},
   126  	}
   127  	f.Create(&ext)
   128  
   129  	f.MustGet(types.NamespacedName{Name: "ext"}, &ext)
   130  
   131  	ext.Spec.Args = []string{"--namespace=foo"}
   132  	f.Update(&ext)
   133  
   134  	var tf v1alpha1.Tiltfile
   135  	f.MustGet(types.NamespacedName{Name: "ext"}, &tf)
   136  	require.Equal(t, []string{"--namespace=foo"}, tf.Spec.Args)
   137  }
   138  
   139  // Verify that no errors get printed if the extension
   140  // appears in the apiserver before the repo appears.
   141  func TestExtensionBeforeRepo(t *testing.T) {
   142  	f := newFixture(t)
   143  
   144  	nn := types.NamespacedName{Name: "ext"}
   145  	ext := v1alpha1.Extension{
   146  		ObjectMeta: metav1.ObjectMeta{
   147  			Name: "ext",
   148  		},
   149  		Spec: v1alpha1.ExtensionSpec{
   150  			RepoName: "my-repo",
   151  			RepoPath: "my-ext",
   152  		},
   153  	}
   154  	f.Create(&ext)
   155  
   156  	f.MustGet(nn, &ext)
   157  	assert.Equal(t, "extension repo not found: my-repo", ext.Status.Error)
   158  	assert.Equal(t, "", f.Stdout())
   159  
   160  	f.setupRepo()
   161  	f.MustReconcile(nn)
   162  	f.MustGet(nn, &ext)
   163  	assert.Equal(t, "", ext.Status.Error)
   164  	assert.Equal(t, f.JoinPath("my-repo", "my-ext", "Tiltfile"), ext.Status.Path)
   165  	assert.Equal(t, "", f.Stdout())
   166  }
   167  
   168  type fixture struct {
   169  	*fake.ControllerFixture
   170  	*tempdir.TempDirFixture
   171  	r  *Reconciler
   172  	ma *analytics.MemoryAnalytics
   173  }
   174  
   175  func newFixture(t *testing.T) *fixture {
   176  	cfb := fake.NewControllerFixtureBuilder(t)
   177  	tf := tempdir.NewTempDirFixture(t)
   178  
   179  	o := tiltanalytics.NewFakeOpter(analytics.OptIn)
   180  	ma, ta := tiltanalytics.NewMemoryTiltAnalyticsForTest(o)
   181  
   182  	r := NewReconciler(cfb.Client, v1alpha1.NewScheme(), ta)
   183  	return &fixture{
   184  		ControllerFixture: cfb.Build(r),
   185  		TempDirFixture:    tf,
   186  		r:                 r,
   187  		ma:                ma,
   188  	}
   189  }
   190  
   191  func (f *fixture) setupRepo() *v1alpha1.ExtensionRepo {
   192  	p := f.JoinPath("my-repo", "my-ext", "Tiltfile")
   193  	f.WriteFile(p, "print('hello-world')")
   194  
   195  	repo := v1alpha1.ExtensionRepo{
   196  		ObjectMeta: metav1.ObjectMeta{
   197  			Name: "my-repo",
   198  		},
   199  		Spec: v1alpha1.ExtensionRepoSpec{
   200  			URL: fmt.Sprintf("file://%s", f.JoinPath("my-repo")),
   201  		},
   202  		Status: v1alpha1.ExtensionRepoStatus{
   203  			Path: f.JoinPath("my-repo"),
   204  		},
   205  	}
   206  	f.Create(&repo)
   207  	return &repo
   208  }