package edgeconfigsync import ( "context" _ "embed" "os" "path/filepath" "testing" "time" "github.com/go-logr/logr/testr" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/yaml.v3" "gotest.tools/v3/fs" ctrl "sigs.k8s.io/controller-runtime" "edge-infra.dev/pkg/k8s/runtime/controller/reconcile" ) //go:embed testdata/edge-registries.yaml var edgeRegistriesYAML []byte type TestContent struct { Example string `yaml:"example"` } func TestMain(m *testing.M) { os.Exit(m.Run()) } func setupTestCtx(t *testing.T) context.Context { logOptions := testr.Options{ LogTimestamp: true, Verbosity: -1, } return ctrl.LoggerInto(context.Background(), testr.NewWithOptions(t, logOptions)) } func TestCompare(t *testing.T) { tests := map[string]struct { oldContent []byte newContent []byte expectChanged bool }{ "Changed": { oldContent: []byte("old"), newContent: []byte("new"), expectChanged: true, }, "NotChanged": { oldContent: []byte("unchanged"), newContent: []byte("unchanged"), expectChanged: false, }, } for name, tc := range tests { t.Run(name, func(t *testing.T) { dir := fs.NewDir(t, DefaultEdgeRegistriesFilepath) defer dir.Remove() dirPath := dir.Path() fp := filepath.Join(dirPath, "test") err := os.WriteFile(fp, tc.oldContent, 0644) require.NoError(t, err) changed, err := compare(fp, tc.newContent) require.NoError(t, err) assert.Equal(t, tc.expectChanged, changed) }) } } func TestSyncFile(t *testing.T) { dir := fs.NewDir(t, DefaultEdgeRegistriesFilepath) defer dir.Remove() dirPath := dir.Path() tests := map[string]struct { f file expectWrite bool }{ "Changed": { f: file{ path: filepath.Join(dirPath, "changed"), desiredContent: TestContent{Example: "changed"}, mode: 0644, }, expectWrite: true, }, "NotChanged": { f: file{ path: filepath.Join(dirPath, "unchanged"), desiredContent: TestContent{Example: "unchanged"}, mode: 0644, }, expectWrite: false, }, } for name, tc := range tests { t.Run(name, func(t *testing.T) { ctx := setupTestCtx(t) orig := TestContent{Example: "unchanged"} origYAML, err := yaml.Marshal(&orig) require.NoError(t, err) err = os.WriteFile(tc.f.path, origYAML, 0644) require.NoError(t, err) fOld, err := os.Open(tc.f.path) require.NoError(t, err) defer fOld.Close() oldInfo, err := fOld.Stat() require.NoError(t, err) oldModTime := oldInfo.ModTime() time.Sleep(10 * time.Millisecond) err = syncFile(ctx, tc.f) require.NoError(t, err) content, err := os.ReadFile(tc.f.path) require.NoError(t, err) fNew, err := os.Open(tc.f.path) require.NoError(t, err) defer fNew.Close() newInfo, err := fNew.Stat() require.NoError(t, err) newModTime := newInfo.ModTime() out := TestContent{} err = yaml.Unmarshal(content, &out) require.NoError(t, err) assert.Equal(t, tc.f.desiredContent, out) switch tc.expectWrite { case true: assert.NotEqual(t, oldModTime, newModTime) case false: assert.Equal(t, oldModTime, newModTime) } }) } } func TestReconcile(t *testing.T) { ctx := setupTestCtx(t) dir := fs.NewDir(t, DefaultEdgeRegistriesFilepath) defer dir.Remove() dirPath := dir.Path() fp := filepath.Join(dirPath, "test") p := Plugin{ EdgeRegistriesFilepath: fp, } res, err := p.Reconcile(ctx, nil, nil) require.NoError(t, err) require.Equal(t, reconcile.ResultSuccess, res) content, err := os.ReadFile(fp) require.NoError(t, err) assert.Equal(t, string(edgeRegistriesYAML), string(content)) }