diff --git a/internal/mqinimerge/mqinimerge.go b/internal/mqinimerge/mqinimerge.go index d7a7f21..e324924 100644 --- a/internal/mqinimerge/mqinimerge.go +++ b/internal/mqinimerge/mqinimerge.go @@ -14,11 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package mqini provides information about queue managers +// Package mqinimerge merges user-supplied INI files into qm.ini and mqat.ini package mqinimerge import ( "bufio" + "bytes" "errors" "fmt" "io/ioutil" @@ -318,14 +319,31 @@ func prepareStanzasToMerge(key string, attrList strings.Builder, iniConfigList [ return iniConfigList, nil } -// writeConfigStanzas writes the INI file updates into corresponding mq ini files. +// writeFileIfChanged writes the specified data to the specified file path +// (just like ioutil.WriteFile), but first checks if this is needed +func writeFileIfChanged(path string, data []byte, perm os.FileMode) error { + current, err := ioutil.ReadFile(path) + if err != nil { + return err + } + // Only write the new file if the it's different from the current file + if !bytes.Equal(current, data) { + err = ioutil.WriteFile(path, data, perm) + if err != nil { + return err + } + } + return nil +} + +// writeConfigStanzas writes the INI file updates into corresponding MQ INI files. func writeConfigStanzas(qmConfig []string, atConfig []string) error { - err := ioutil.WriteFile(filepath.Join(qmgrDir, "qm.ini"), []byte(strings.Join(qmConfig, "\n")), 0644) + err := writeFileIfChanged(filepath.Join(qmgrDir, "qm.ini"), []byte(strings.Join(qmConfig, "\n")), 0644) if err != nil { return err } - err = ioutil.WriteFile(filepath.Join(qmgrDir, "mqat.ini"), []byte(strings.Join(atConfig, "\n")), 0644) + err = writeFileIfChanged(filepath.Join(qmgrDir, "mqat.ini"), []byte(strings.Join(atConfig, "\n")), 0644) if err != nil { return err } diff --git a/internal/mqinimerge/mqinimerge_test.go b/internal/mqinimerge/mqinimerge_test.go index 40ef53f..fd20abd 100644 --- a/internal/mqinimerge/mqinimerge_test.go +++ b/internal/mqinimerge/mqinimerge_test.go @@ -17,9 +17,13 @@ package mqinimerge import ( "bufio" + "fmt" "io/ioutil" + "os" + "path/filepath" "strings" "testing" + "time" ) func TestIniFileStanzas(t *testing.T) { @@ -205,3 +209,48 @@ func checkReturns(stanza string, isqmini bool, shouldexist bool, t *testing.T) { } } } + +var writeFileIfChangedTests = []struct { + before []byte + after []byte + same bool +}{ + {[]byte("ABC€"), []byte("ABC€"), true}, + {[]byte("ABC€"), []byte("ABC$"), false}, + {[]byte("ABC€"), []byte("BBC€"), false}, +} + +func TestWriteFileIfChanged(t *testing.T) { + tmpFile := filepath.Join(os.TempDir(), t.Name()) + t.Logf("Using temp file %v", tmpFile) + for i, table := range writeFileIfChangedTests { + t.Run(fmt.Sprintf("%v", i), func(t *testing.T) { + err := ioutil.WriteFile(tmpFile, table.before, 0600) + time.Sleep(time.Second * 1) + defer os.Remove(tmpFile) + fi, err := os.Stat(tmpFile) + if err != nil { + t.Fatal(err) + } + beforeMod := fi.ModTime() + err = writeFileIfChanged(tmpFile, table.after, 0600) + if err != nil { + t.Error(err) + } + fi, err = os.Stat(tmpFile) + if err != nil { + t.Error(err) + } + afterMod := fi.ModTime() + if table.same { + if beforeMod != afterMod { + t.Errorf("Expected file timestamps to be the same (%v); got %v", beforeMod, afterMod) + } + } else { + if beforeMod == afterMod { + t.Errorf("Expected file timestamp to be different got %v and %v", beforeMod, afterMod) + } + } + }) + } +}