From 15f87d3417bab761fab8edbea30837b2365834b4 Mon Sep 17 00:00:00 2001 From: petruki <31597636+petruki@users.noreply.github.com> Date: Sun, 11 Aug 2024 16:28:16 -0700 Subject: [PATCH] Added logic signatures for both repo and API sync functions --- src/core/core_test.go | 2 +- src/core/handler.go | 58 +++++++++++++++++++++++++++------------- src/core/handler_test.go | 40 +++++++++++++++++++++++++-- src/model/snapshot.go | 3 ++- 4 files changed, 80 insertions(+), 23 deletions(-) diff --git a/src/core/core_test.go b/src/core/core_test.go index 4a3abf8..d73635b 100644 --- a/src/core/core_test.go +++ b/src/core/core_test.go @@ -71,7 +71,7 @@ func givenAccount() model.Account { Domain: model.DomainDetails{ ID: "123", Name: "Switcher GitOps", - Version: "", + Version: "0", LastCommit: "", LastDate: "", Status: model.StatusOutSync, diff --git a/src/core/handler.go b/src/core/handler.go index 0e998b2..6c6a539 100644 --- a/src/core/handler.go +++ b/src/core/handler.go @@ -70,36 +70,32 @@ func (c *CoreHandler) syncUp(account model.Account, repositoryData *model.Reposi // Update account status: Out of sync account.Domain.LastCommit = repositoryData.CommitHash account.Domain.LastDate = repositoryData.CommitDate - account.Domain.Status = model.StatusOutSync - account.Domain.Message = "Syncing up..." - c.AccountRepository.Update(&account) + c.updateDomainStatus(account, model.StatusOutSync, "Syncing up...") // Check for changes - diff, err := c.checkForChanges(account.Domain.ID, account.Environment, repositoryData.Content) + diff, snapshotApi, err := c.checkForChanges(account.Domain.ID, account.Environment, repositoryData.Content) if err != nil { - // Update account status: Error - account.Domain.Status = model.StatusError - account.Domain.Message = "Error syncing up" - c.AccountRepository.Update(&account) + c.updateDomainStatus(account, model.StatusError, "Failed to check for changes") return } - // Apply changes - c.applyChanges(account, diff) + if snapshotApi.Domain.Version > account.Domain.Version { + account = c.applyChangesToRepository(account, snapshotApi.Domain) + } else if len(diff.Changes) > 0 { + account = c.applyChangesToAPI(account, repositoryData) + } // Update account status: Synced - account.Domain.Status = model.StatusSynced - account.Domain.Message = "Synced successfully" - c.AccountRepository.Update(&account) + c.updateDomainStatus(account, model.StatusSynced, "Synced successfully") } -func (c *CoreHandler) checkForChanges(domainId string, environment string, content string) (model.DiffResult, error) { +func (c *CoreHandler) checkForChanges(domainId string, environment string, content string) (model.DiffResult, model.Snapshot, error) { // Get Snapshot from API snapshotJsonFromApi, err := c.ApiService.FetchSnapshot(domainId, environment) if err != nil { - return model.DiffResult{}, err + return model.DiffResult{}, model.Snapshot{}, err } // Convert API JSON to model.Snapshot @@ -115,11 +111,29 @@ func (c *CoreHandler) checkForChanges(domainId string, environment string, conte diffChanged := c.ComparatorService.CheckSnapshotDiff(left, right, CHANGED) diffDeleted := c.ComparatorService.CheckSnapshotDiff(left, right, DELETED) - return c.ComparatorService.MergeResults([]model.DiffResult{diffNew, diffChanged, diffDeleted}), nil + return c.ComparatorService.MergeResults([]model.DiffResult{diffNew, diffChanged, diffDeleted}), snapshotApi.Snapshot, nil } -func (c *CoreHandler) applyChanges(account model.Account, diff model.DiffResult) { - // Apply changes +func (c *CoreHandler) applyChangesToAPI(account model.Account, repositoryData *model.RepositoryData) model.Account { + // Push changes to API + println("Pushing changes to API") + + // Update domain + account.Domain.Version = "2" + account.Domain.LastCommit = repositoryData.CommitHash + + return account +} + +func (c *CoreHandler) applyChangesToRepository(account model.Account, domain model.Domain) model.Account { + // Push changes to repository + println("Pushing changes to repository") + + // Update domain + account.Domain.Version = domain.Version + account.Domain.LastCommit = "111" + + return account } func isRepositoryOutSync(account model.Account, lastCommit string) bool { @@ -127,7 +141,13 @@ func isRepositoryOutSync(account model.Account, lastCommit string) bool { } func getTimeWindow(window string) (int, time.Duration) { - // Convert window string to time.Duration duration, _ := time.ParseDuration(window) return 1, duration } + +func (c *CoreHandler) updateDomainStatus(account model.Account, status string, message string) { + account.Domain.Status = status + account.Domain.Message = message + account.Domain.LastDate = time.Now().Format(time.ANSIC) + c.AccountRepository.Update(&account) +} diff --git a/src/core/handler_test.go b/src/core/handler_test.go index 5b6305d..e059d09 100644 --- a/src/core/handler_test.go +++ b/src/core/handler_test.go @@ -64,6 +64,7 @@ func TestStartAccountHandler(t *testing.T) { coreHandler = NewCoreHandler(coreHandler.AccountRepository, fakeGitService, fakeApiService, NewComparatorService()) account := givenAccount() + account.Domain.Version = "1" coreHandler.AccountRepository.Create(&account) // Prepare goroutine signals @@ -82,8 +83,43 @@ func TestStartAccountHandler(t *testing.T) { // Assert accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainId(account.Domain.ID) assert.Equal(t, model.StatusSynced, accountFromDb.Domain.Status) - assert.Equal(t, "Synced successfully", accountFromDb.Domain.Message) + assert.Contains(t, accountFromDb.Domain.Message, "Synced successfully") assert.Equal(t, "123", accountFromDb.Domain.LastCommit) + assert.Equal(t, "2", accountFromDb.Domain.Version) + assert.NotEqual(t, "", accountFromDb.Domain.LastDate) + + tearDown() + }) + + t.Run("Should sync successfully when API has a newer version", func(t *testing.T) { + // Given + fakeGitService := NewFakeGitService() + fakeApiService := NewFakeApiService(false) + coreHandler = NewCoreHandler(coreHandler.AccountRepository, fakeGitService, fakeApiService, NewComparatorService()) + + account := givenAccount() + account.Domain.Version = "0" + coreHandler.AccountRepository.Create(&account) + + // Prepare goroutine signals + var wg sync.WaitGroup + quit := make(chan bool) + wg.Add(1) + + // Test + go coreHandler.StartAccountHandler(account, quit, &wg) + + // Wait for the goroutine to run and terminate + time.Sleep(1 * time.Second) + quit <- true + wg.Wait() + + // Assert + accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainId(account.Domain.ID) + assert.Equal(t, model.StatusSynced, accountFromDb.Domain.Status) + assert.Contains(t, accountFromDb.Domain.Message, "Synced successfully") + assert.Equal(t, "111", accountFromDb.Domain.LastCommit) + assert.Equal(t, "1", accountFromDb.Domain.Version) assert.NotEqual(t, "", accountFromDb.Domain.LastDate) tearDown() @@ -114,7 +150,7 @@ func TestStartAccountHandler(t *testing.T) { // Assert accountFromDb, _ := coreHandler.AccountRepository.FetchByDomainId(account.Domain.ID) assert.Equal(t, model.StatusError, accountFromDb.Domain.Status) - assert.Equal(t, "Error syncing up", accountFromDb.Domain.Message) + assert.Contains(t, accountFromDb.Domain.Message, "Failed to check for changes") assert.Equal(t, "123", accountFromDb.Domain.LastCommit) assert.NotEqual(t, "", accountFromDb.Domain.LastDate) diff --git a/src/model/snapshot.go b/src/model/snapshot.go index 0dfb9a8..965951f 100644 --- a/src/model/snapshot.go +++ b/src/model/snapshot.go @@ -1,7 +1,8 @@ package model type Domain struct { - Group []Group `json:"group,omitempty"` + Group []Group `json:"group,omitempty"` + Version string `json:"version,omitempty"` } type Group struct {