Skip to content

Commit

Permalink
Optimize CCom performance (#246)
Browse files Browse the repository at this point in the history
* Use ccomc directly for loading list entries

* Fix bug and add tests

* Refactoring
  • Loading branch information
marcauberer committed Dec 4, 2021
1 parent d644378 commit c8e2887
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src/project/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func loadComposeFileSingleService(
logError("Compose file not found in template "+templateTypeName+"-"+serviceName, true)
}
// Evaluate conditional sections
evaluated := util.EvaluateConditionalSectionsToString(
evaluated := util.EvaluateConditionalSectionsInYamlToString(
opt.WorkingDir+opt.ComposeFileName,
selectedTemplates,
project.Vars,
Expand Down
31 changes: 9 additions & 22 deletions src/util/conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ import (
// ---------------------------------------------------------------- Public functions ---------------------------------------------------------------

// EvaluateConditionalSections evaluates conditional sections in template data
func EvaluateConditionalSections(
filePath string,
selected *model.SelectedTemplates,
varMap model.Vars,
) {
func EvaluateConditionalSections(filePath string, selected *model.SelectedTemplates, varMap model.Vars) {
dataString := prepareInputData(selected, varMap)
// Execute CCom
// #nosec G204
Expand All @@ -32,16 +28,13 @@ func EvaluateConditionalSections(
}
}

// EvaluateConditionalSectionsToString evaluates conditional sections in template data
func EvaluateConditionalSectionsToString(
input string,
selected *model.SelectedTemplates,
varMap model.Vars,
) string {
// EvaluateConditionalSectionsInYamlToString evaluates conditional sections in template data
func EvaluateConditionalSectionsInYamlToString(input string, selected *model.SelectedTemplates, varMap model.Vars) string {
dataString := prepareInputData(selected, varMap)
// Execute CCom
ccomcPath := getCComCompilerPath()
// #nosec G204
cmd := exec.Command("ccom", "-l", "yml", "-d", dataString, "-s", input)
cmd := exec.Command(ccomcPath, "false", input, dataString, "#", "", "")
output, err := cmd.CombinedOutput()
if err != nil {
ErrorLogger.Println("Could not execute CCom: " + string(output) + ": " + err.Error())
Expand All @@ -51,20 +44,17 @@ func EvaluateConditionalSectionsToString(
}

// EvaluateCondition evaluates the given condition to a boolean result
func EvaluateCondition(
condition string,
selected *model.SelectedTemplates,
varMap model.Vars,
) bool {
func EvaluateCondition(condition string, selected *model.SelectedTemplates, varMap model.Vars) bool {
// Cancel if condition is 'true' or 'false'
if condition == "true" || condition == "false" {
return condition == "true"
}
// Prepare data input for CCom
dataString := prepareInputData(selected, varMap)
// Execute CCom
ccomcPath := getCComCompilerPath()
// #nosec G204
cmd := exec.Command("ccom", "-m", "-s", "-d", dataString, condition)
cmd := exec.Command(ccomcPath, "true", condition, dataString, "", "", "")
output, err := cmd.CombinedOutput()
if err != nil {
WarningLogger.Println("CCom returned with an error: " + string(output) + ": " + err.Error())
Expand All @@ -91,10 +81,7 @@ func EnsureDockerIsRunning() {

// --------------------------------------------------------------- Private functions ---------------------------------------------------------------

func prepareInputData(
selected *model.SelectedTemplates,
varMap model.Vars,
) string {
func prepareInputData(selected *model.SelectedTemplates, varMap model.Vars) string {
// Create data object
data := model.CComDataInput{
Services: *selected,
Expand Down
22 changes: 11 additions & 11 deletions src/util/conditions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,40 +37,40 @@ var varMap = map[string]string{
"BAR": "test1",
}

// ---------------------------------------------------------------- EvaluateConditionalSection ---------------------------------------------------------------
// --------------------------------------------------------- EvaluateConditionalSectionsInYaml ------------------------------------------------------

func TestEvaluateConditionalSectionToString_True1(t *testing.T) {
func TestEvaluateConditionalSectionsInYamlToString_True1(t *testing.T) {
content := "property1: true\n#? if services.backend contains label == \"Wordpress\" {\n#property2: false\n#? }\nproperty3: true"
expectation := "property1: true\nproperty2: false\nproperty3: true"
result := EvaluateConditionalSectionsToString(content, templateData, varMap)
result := EvaluateConditionalSectionsInYamlToString(content, templateData, varMap)
assert.Equal(t, expectation, result)
}

func TestEvaluateConditionalSectionToString_True2(t *testing.T) {
func TestEvaluateConditionalSectionsInYamlToString_True2(t *testing.T) {
content := "property1: true\n#? if services.frontend contains name == \"vue\" | has templates.backend {\n#property2: false\n#? }\nproperty3: true"
expectation := "property1: true\nproperty2: false\nproperty3: true"
result := EvaluateConditionalSectionsToString(content, templateData, varMap)
result := EvaluateConditionalSectionsInYamlToString(content, templateData, varMap)
assert.Equal(t, expectation, result)
}

func TestEvaluateConditionalSectionToString_True3(t *testing.T) {
func TestEvaluateConditionalSectionsInYamlToString_True3(t *testing.T) {
content := "property1: true\n#? if var.BAR == \"test1\" {\n#property2: false\n#? }\nproperty3: true"
expectation := "property1: true\nproperty2: false\nproperty3: true"
result := EvaluateConditionalSectionsToString(content, templateData, varMap)
result := EvaluateConditionalSectionsInYamlToString(content, templateData, varMap)
assert.Equal(t, expectation, result)
}

func TestEvaluateConditionalSectionToString_False1(t *testing.T) {
func TestEvaluateConditionalSectionsInYamlToString_False1(t *testing.T) {
content := "property1: true\n#? if var.BAR == \"invalid\" {\n# property2: false\n#? }\nproperty3: true"
expectation := "property1: true\nproperty3: true"
result := EvaluateConditionalSectionsToString(content, templateData, varMap)
result := EvaluateConditionalSectionsInYamlToString(content, templateData, varMap)
assert.Equal(t, expectation, result)
}

func TestEvaluateConditionalSectionToString_False2(t *testing.T) {
func TestEvaluateConditionalSectionsInYamlToString_False2(t *testing.T) {
content := "property1: true\n#? if has services.database {\n# property2: false\n#? }\nproperty3: true"
expectation := "property1: true\nproperty3: true"
result := EvaluateConditionalSectionsToString(content, templateData, varMap)
result := EvaluateConditionalSectionsInYamlToString(content, templateData, varMap)
assert.Equal(t, expectation, result)
}

Expand Down
7 changes: 7 additions & 0 deletions src/util/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,13 @@ func getLogfilesPath() string {
return path[:strings.LastIndex(path, "/")] + "/log"
}

func getCComCompilerPath() string {
if isWindows() { // Windows
return "ccomc"
}
return "/usr/lib/ccom/ccomc" // Linux + Docker
}

func getOuterVolumePathOnDockerizedEnvironment() string {
// Obtain Docker client
client, err := newClientWithOpts(client.FromEnv)
Expand Down
28 changes: 28 additions & 0 deletions src/util/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -684,3 +684,31 @@ func TestGetLogfilesPath6(t *testing.T) {
// Assert
assert.Equal(t, expectedPath, result)
}

// -------------------------------------------------------------- getCComCompilerPath --------------------------------------------------------------

func TestGetCComCompilerPath1(t *testing.T) {
// Test data
expectedPath := "/usr/lib/ccom/ccomc"
// Mock functions
isWindows = func() bool {
return false
}
// Execute test
actualPath := getCComCompilerPath()
// Assert
assert.Equal(t, expectedPath, actualPath)
}

func TestGetCComCompilerPath2(t *testing.T) {
// Test data
expectedPath := "ccomc"
// Mock functions
isWindows = func() bool {
return true
}
// Execute test
actualPath := getCComCompilerPath()
// Assert
assert.Equal(t, expectedPath, actualPath)
}

0 comments on commit c8e2887

Please sign in to comment.