Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to cleanup DVO database #281

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cleaner.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ func vacuumDB(connection *sql.DB) (int, error) {
}

// cleanup function starts the cleanup operation
func cleanup(configuration *ConfigStruct, connection *sql.DB, cliFlags CliFlags) (int, error) {
func cleanup(configuration *ConfigStruct, connection *sql.DB, cliFlags CliFlags, schema string) (int, error) {
// cleanup operation
clusterList, improperClusterCounter, err := readClusterList(
configuration.Cleaner.ClusterListFile,
Expand All @@ -286,7 +286,7 @@ func cleanup(configuration *ConfigStruct, connection *sql.DB, cliFlags CliFlags)
log.Err(err).Msg("Read cluster list")
return ExitStatusPerformCleanupError, err
}
deletionsForTable, err := performCleanupInDB(connection, clusterList)
deletionsForTable, err := performCleanupInDB(connection, clusterList, schema)
if err != nil {
log.Err(err).Msg("Performing cleanup")
return ExitStatusPerformCleanupError, err
Expand Down Expand Up @@ -364,7 +364,7 @@ func doSelectedOperation(configuration *ConfigStruct, connection *sql.DB, cliFla
case cliFlags.VacuumDatabase:
return vacuumDB(connection)
case cliFlags.PerformCleanup:
return cleanup(configuration, connection, cliFlags)
return cleanup(configuration, connection, cliFlags, configuration.Storage.Schema)
case cliFlags.DetectMultipleRuleDisable:
return detectMultipleRuleDisable(connection, cliFlags)
case cliFlags.FillInDatabase:
Expand Down
10 changes: 5 additions & 5 deletions cleaner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,7 @@ func TestCleanupNoConnection(t *testing.T) {
}

// call the tested function
status, err := main.Cleanup(&configuration, nil, cliFlags)
status, err := main.Cleanup(&configuration, nil, cliFlags, main.DBSchemaOCPRecommendations)

// error is expected
assert.Error(t, err, "error is expected while calling main.cleanup")
Expand All @@ -903,7 +903,7 @@ func TestCleanupOnReadClusterListError(t *testing.T) {
}

// call the tested function
status, err := main.Cleanup(&configuration, nil, cliFlags)
status, err := main.Cleanup(&configuration, nil, cliFlags, main.DBSchemaOCPRecommendations)

// error is expected
assert.Error(t, err, "error is expected while calling main.cleanup")
Expand Down Expand Up @@ -935,7 +935,7 @@ func TestCleanup(t *testing.T) {
}

// call the tested function
status, err := main.Cleanup(&configuration, connection, cliFlags)
status, err := main.Cleanup(&configuration, connection, cliFlags, main.DBSchemaOCPRecommendations)

// error is not expected
assert.NoError(t, err, "error is not expected while calling main.cleanup")
Expand Down Expand Up @@ -967,7 +967,7 @@ func TestCleanupPrintSummaryTable(t *testing.T) {
}

// call the tested function
status, err := main.Cleanup(&configuration, connection, cliFlags)
status, err := main.Cleanup(&configuration, connection, cliFlags, main.DBSchemaOCPRecommendations)

// error is not expected
assert.NoError(t, err, "error is not expected while calling main.cleanup")
Expand Down Expand Up @@ -1021,7 +1021,7 @@ func TestCleanupCheckSummaryTableContent(t *testing.T) {

// call the tested function
output, err := capture.StandardOutput(func() {
status, _ = main.Cleanup(&configuration, connection, cliFlags)
status, _ = main.Cleanup(&configuration, connection, cliFlags, main.DBSchemaOCPRecommendations)
})

// check the captured text
Expand Down
2 changes: 1 addition & 1 deletion config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pg_host = "localhost"
pg_port = 5432
pg_db_name = "aggregator"
pg_params = "sslmode=disable"
schema = "dvo_recommendations"
schema = "ocp_recommendations"

[logging]
debug = true
Expand Down
3 changes: 2 additions & 1 deletion export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ package main
// https://medium.com/@robiplus/golang-trick-export-for-test-aa16cbd7b8cd
// to see why this trick is needed.
var (
TablesAndKeys = tablesAndKeys
TablesAndKeysInOCPDatabase = tablesAndKeysInOCPDatabase
TablesAndKeysInDVODatabase = tablesAndKeysInDVODatabase

// functions from the storage.go source file
ReadOrgID = readOrgID
Expand Down
25 changes: 22 additions & 3 deletions storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -571,9 +571,9 @@ func deleteRecordFromTable(connection *sql.DB, table, key string, clusterName Cl
return int(affected), nil
}

// tablesAndKeys contains list of all tables together with keys used to select
// tablesAndKeysInOCPDatabase contains list of all tables together with keys used to select
// records to be deleted
var tablesAndKeys = [...]TableAndKey{
var tablesAndKeysInOCPDatabase = []TableAndKey{
{
TableName: "cluster_rule_toggle",
KeyName: "cluster_id",
Expand Down Expand Up @@ -605,6 +605,13 @@ var tablesAndKeys = [...]TableAndKey{
},
}

var tablesAndKeysInDVODatabase = []TableAndKey{
{
TableName: "dvo_report",
KeyName: "cluster_id",
},
}

// performVacuumDB vacuums the whole database
func performVacuumDB(connection *sql.DB) error {
log.Info().Msg("Vacuuming started")
Expand All @@ -621,7 +628,7 @@ func performVacuumDB(connection *sql.DB) error {

// performCleanupInDB function cleans up all data for selected cluster names
func performCleanupInDB(connection *sql.DB,
clusterList ClusterList) (map[string]int, error) {
clusterList ClusterList, schema string) (map[string]int, error) {
// return value
deletionsForTable := make(map[string]int)

Expand All @@ -631,6 +638,18 @@ func performCleanupInDB(connection *sql.DB,
return deletionsForTable, errors.New(connectionNotEstablished)
}

// this is actually shorter than using map + map selector + test for key existence
// and it allow us to do fine tuning for (any) DB schema in future
var tablesAndKeys []TableAndKey
switch schema {
case DBSchemaOCPRecommendations:
tablesAndKeys = tablesAndKeysInOCPDatabase
case DBSchemaDVORecommendations:
tablesAndKeys = tablesAndKeysInDVODatabase
default:
return deletionsForTable, fmt.Errorf("Invalid DB schema to be cleaned up: '%s'", schema)
}

// initialize counters
for _, tableAndKey := range tablesAndKeys {
deletionsForTable[tableAndKey.TableName] = 0
Expand Down
99 changes: 91 additions & 8 deletions storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1576,9 +1576,9 @@ func TestFillInDatabaseByTestDataOnWrongSchema(t *testing.T) {
checkAllExpectations(t, mock)
}

// TestPerformCleanupInDB checks the basic behaviour of
// performCleanupInDB function.
func TestPerformCleanupInDB(t *testing.T) {
// TestPerformCleanupInDBForOCPDatabase checks the basic behaviour of
// performCleanupInDBForOCPDatabase function.
func TestPerformCleanupInDBForOCPDatabase(t *testing.T) {
expectedResult := make(map[string]int)

// prepare new mocked connection to database
Expand All @@ -1592,7 +1592,7 @@ func TestPerformCleanupInDB(t *testing.T) {
}

for _, clusterName := range clusterNames {
for _, tableAndKey := range cleaner.TablesAndKeys {
for _, tableAndKey := range cleaner.TablesAndKeysInOCPDatabase {
// expected query performed by tested function
expectedExec := fmt.Sprintf("DELETE FROM %v WHERE %v = \\$", tableAndKey.TableName, tableAndKey.KeyName)
mock.ExpectExec(expectedExec).WithArgs(clusterName).WillReturnResult(sqlmock.NewResult(1, 2))
Expand All @@ -1604,7 +1604,7 @@ func TestPerformCleanupInDB(t *testing.T) {

mock.ExpectClose()

deletedRows, err := cleaner.PerformCleanupInDB(connection, clusterNames)
deletedRows, err := cleaner.PerformCleanupInDB(connection, clusterNames, main.DBSchemaOCPRecommendations)
assert.NoError(t, err, "error not expected while calling tested function")

// check tables have correct number of deleted rows for each table
Expand All @@ -1619,6 +1619,89 @@ func TestPerformCleanupInDB(t *testing.T) {
checkAllExpectations(t, mock)
}

// TestPerformCleanupInDBForDVODatabase checks the basic behaviour of
// performCleanupInDBForDVODatabase function.
func TestPerformCleanupInDBForDVODatabase(t *testing.T) {
expectedResult := make(map[string]int)

// prepare new mocked connection to database
connection, mock, err := sqlmock.New()
assert.NoError(t, err, "error creating SQL mock")

clusterNames := cleaner.ClusterList{
"00000000-0000-0000-0000-000000000000",
"11111111-1111-1111-1111-111111111111",
"5d5892d4-1f74-4ccf-91af-548dfc9767aa",
}

for _, clusterName := range clusterNames {
for _, tableAndKey := range cleaner.TablesAndKeysInDVODatabase {
// expected query performed by tested function
expectedExec := fmt.Sprintf("DELETE FROM %v WHERE %v = \\$", tableAndKey.TableName, tableAndKey.KeyName)
mock.ExpectExec(expectedExec).WithArgs(clusterName).WillReturnResult(sqlmock.NewResult(1, 2))

// two deleted rows for each cluster
expectedResult[tableAndKey.TableName] += 2
}
}

mock.ExpectClose()

deletedRows, err := cleaner.PerformCleanupInDB(connection, clusterNames, main.DBSchemaDVORecommendations)
assert.NoError(t, err, "error not expected while calling tested function")

// check tables have correct number of deleted rows for each table
for tableName, deletedRowCount := range deletedRows {
assert.Equal(t, expectedResult[tableName], deletedRowCount)
}

// check if DB can be closed successfully
checkConnectionClose(t, connection)

// check all DB expectactions happened correctly
checkAllExpectations(t, mock)
}

// TestPerformCleanupInDBNullSchema checks the basic behaviour of
// performCleanupInDB function.
func TestPerformCleanupInDBNullSchema(t *testing.T) {
// prepare new mocked connection to database
connection, mock, err := sqlmock.New()
assert.NoError(t, err, "error creating SQL mock")

clusterNames := cleaner.ClusterList{
"00000000-0000-0000-0000-000000000000",
"11111111-1111-1111-1111-111111111111",
"5d5892d4-1f74-4ccf-91af-548dfc9767aa",
}

_, err = cleaner.PerformCleanupInDB(connection, clusterNames, "")
assert.Error(t, err, "error is expected while calling tested function")

// check all DB expectactions happened correctly
checkAllExpectations(t, mock)
}

// TestPerformCleanupInDBWrongSchema checks the basic behaviour of
// performCleanupInDB function.
func TestPerformCleanupInDBWrongSchema(t *testing.T) {
// prepare new mocked connection to database
connection, mock, err := sqlmock.New()
assert.NoError(t, err, "error creating SQL mock")

clusterNames := cleaner.ClusterList{
"00000000-0000-0000-0000-000000000000",
"11111111-1111-1111-1111-111111111111",
"5d5892d4-1f74-4ccf-91af-548dfc9767aa",
}

_, err = cleaner.PerformCleanupInDB(connection, clusterNames, "wrong schema")
assert.Error(t, err, "error is expected while calling tested function")

// check all DB expectactions happened correctly
checkAllExpectations(t, mock)
}

// TestPerformCleanupInDBOnDeleteError checks the basic behaviour of
// performCleanupInDB function when error in called DeleteRecordFromTable.
// is thrown
Expand All @@ -1639,7 +1722,7 @@ func TestPerformCleanupInDBOnDeleteError(t *testing.T) {
}

for _, clusterName := range clusterNames {
for _, tableAndKey := range cleaner.TablesAndKeys {
for _, tableAndKey := range cleaner.TablesAndKeysInOCPDatabase {
// expected query performed by tested function
expectedExec := fmt.Sprintf("DELETE FROM %v WHERE %v = \\$", tableAndKey.TableName, tableAndKey.KeyName)
mock.ExpectExec(expectedExec).WithArgs(clusterName).WillReturnError(mockedError)
Expand All @@ -1651,7 +1734,7 @@ func TestPerformCleanupInDBOnDeleteError(t *testing.T) {

mock.ExpectClose()

deletedRows, err := cleaner.PerformCleanupInDB(connection, clusterNames)
deletedRows, err := cleaner.PerformCleanupInDB(connection, clusterNames, main.DBSchemaOCPRecommendations)
assert.NoError(t, err, "error not expected while calling tested function")

// check tables have correct number of deleted rows for each table
Expand All @@ -1678,7 +1761,7 @@ func TestPerformCleanupInDBNoConnection(t *testing.T) {
"5d5892d4-1f74-4ccf-91af-548dfc9767aa",
}

_, err := cleaner.PerformCleanupInDB(connection, clusterNames)
_, err := cleaner.PerformCleanupInDB(connection, clusterNames, main.DBSchemaOCPRecommendations)

assert.Error(t, err, "error is expected while calling tested function")
}
Expand Down