Skip to content

Commit cdc7841

Browse files
authored
test: CheckForExistingPostmaster implementation easier to test (cloudnative-pg#370)
We weren't testing the positive case in our unit tests, that is when the `postmaster` process actually exists. In order to do that, the implementation of `CheckForExistingPostmaster` had to be changed to allow the code to inject a custom process name. Closes cloudnative-pg#369 Signed-off-by: Leonardo Cecchi <leonardo.cecchi@enterprisedb.com>
1 parent d54dbdf commit cdc7841

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

pkg/management/postgres/instance.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ func (instance *Instance) Reload() error {
396396
// Run this instance returning an OS process needed
397397
// to control the instance execution
398398
func (instance Instance) Run() (*execlog.StreamingCmd, error) {
399-
process, err := instance.CheckForExistingPostmaster()
399+
process, err := instance.CheckForExistingPostmaster(postgresName)
400400
if err != nil {
401401
return nil, err
402402
}

pkg/management/postgres/pidfile.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"strings"
2424

2525
"github.com/mitchellh/go-ps"
26+
"k8s.io/utils/strings/slices"
2627

2728
"github.com/cloudnative-pg/cloudnative-pg/pkg/fileutils"
2829
"github.com/cloudnative-pg/cloudnative-pg/pkg/management/log"
@@ -39,7 +40,12 @@ const PostgresqlPidFile = "postmaster.pid" //wokeignore:rule=master
3940
// directory and check the existence of the relative process. If the
4041
// process exists, then that process entry is returned.
4142
// If it doesn't exist then the PID file is stale and is removed.
42-
func (instance *Instance) CheckForExistingPostmaster() (*os.Process, error) {
43+
//
44+
// We are requiring a list of PostgreSQL executables that is used
45+
// to check if the process with the ID read from the PID file
46+
// is really a postmaster. This isn't really needed per se, but
47+
// allows this function to be easier to test.
48+
func (instance *Instance) CheckForExistingPostmaster(postgresExecutables ...string) (*os.Process, error) {
4349
pidFile := path.Join(instance.PgData, PostgresqlPidFile)
4450
contextLog := log.WithValues("file", pidFile)
4551
pidFileContents, pid, err := instance.GetPostmasterPidFromFile(pidFile)
@@ -64,7 +70,7 @@ func (instance *Instance) CheckForExistingPostmaster() (*os.Process, error) {
6470
return nil, instance.CleanUpStalePid()
6571
}
6672

67-
if process.Executable() != postgresName {
73+
if !slices.Contains(postgresExecutables, process.Executable()) {
6874
// The process is not running PostgreSQL and this PID file is stale
6975
contextLog.Info("The PID file is stale (executable mismatch), deleting it",
7076
"pidFileContents", pidFileContents, "postgresExecutable", process.Executable())

pkg/management/postgres/pidfile_test.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import (
2222
"os"
2323
"path/filepath"
2424

25+
"github.com/mitchellh/go-ps"
26+
2527
"github.com/cloudnative-pg/cloudnative-pg/pkg/fileutils"
2628

2729
. "github.com/onsi/ginkgo/v2"
@@ -49,7 +51,7 @@ var _ = Describe("the detection of a postmaster process using the pid file", fun
4951
instance := NewInstance()
5052
instance.PgData = pgdata
5153
instance.SocketDirectory = socketDir
52-
process, err := instance.CheckForExistingPostmaster()
54+
process, err := instance.CheckForExistingPostmaster(postgresName)
5355
Expect(err).ShouldNot(HaveOccurred())
5456
Expect(process).To(BeNil())
5557
})
@@ -67,7 +69,7 @@ var _ = Describe("the detection of a postmaster process using the pid file", fun
6769
err = ioutil.WriteFile(filepath.Join(socketDir, ".s.PGSQL.5432.lock"), []byte("1234"), 0o400)
6870
Expect(err).ShouldNot(HaveOccurred())
6971

70-
process, err := instance.CheckForExistingPostmaster()
72+
process, err := instance.CheckForExistingPostmaster(postgresName)
7173
Expect(err).ShouldNot(HaveOccurred())
7274
Expect(process).To(BeNil())
7375

@@ -89,10 +91,16 @@ var _ = Describe("the detection of a postmaster process using the pid file", fun
8991
filepath.Join(pgdata, PostgresqlPidFile),
9092
[]byte(fmt.Sprintf("%v", myPid)), 0o400)
9193
Expect(err).ShouldNot(HaveOccurred())
94+
myProcess, err := ps.FindProcess(myPid)
95+
Expect(err).ShouldNot(HaveOccurred())
96+
myExecutable := myProcess.Executable()
9297

93-
process, err := instance.CheckForExistingPostmaster()
98+
process, err := instance.CheckForExistingPostmaster(myExecutable)
9499
Expect(err).ShouldNot(HaveOccurred())
95-
// to be null because executable file name is not postgres
96-
Expect(process).To(BeNil())
100+
Expect(process).ToNot(BeNil())
101+
102+
_, err = instance.CheckForExistingPostmaster(myExecutable, "not_existent_executable")
103+
Expect(err).ShouldNot(HaveOccurred())
104+
Expect(process).ToNot(BeNil())
97105
})
98106
})

0 commit comments

Comments
 (0)