blob: 201fc711a26c4cb5dc2d9e9eb38489438e965109 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <glog/logging.h>
#include "kudu/gutil/port.h"
#include "kudu/util/env.h"
#include "kudu/util/path_util.h"
#include "kudu/util/status.h"
#include "kudu/util/subprocess.h" // IWYU pragma: keep
#include "kudu/util/test_util.h"
namespace kudu {
namespace postgres {
// Wrapper around Postgres to be used in MiniCluster for services requiring a
// database connection (e.g. Apache Ranger).
class MiniPostgres {
public:
explicit MiniPostgres(std::string host)
: MiniPostgres(GetTestDataDirectory(), std::move(host)) {}
~MiniPostgres();
MiniPostgres(std::string data_root, std::string host)
: data_root_(std::move(data_root)),
host_(std::move(host)),
bin_dir_(GetBinDir()) {}
Status Start();
Status Stop();
// Creates a Postgres user with the specified name. If super is true, the
// created user will be a superuser, meaning all permission checks will be
// bypasssed[1].
//
// 1. https://www.postgresql.org/docs/12/role-attributes.html
Status AddUser(const std::string& user, bool super);
// Creates a database with the specified name. The owner has privileges to
// remove the database with all objects in it, even if they have different
// owners[1].
//
// 1. https://www.postgresql.org/docs/12/manage-ag-createdb.html
Status CreateDb(const std::string& db, const std::string& owner);
uint16_t bound_port() const {
CHECK_NE(0, port_);
return port_;
}
const std::string& host() const {
return host_;
}
std::string pg_root() const {
return JoinPathSegments(data_root_, "postgres");
}
std::string pg_bin_dir() const {
return JoinPathSegments(bin_dir_, "postgres");
}
bool IsFirstRun() const { return !Env::Default()->FileExists(pg_root()); }
bool IsStarted() const { return process_ && process_->IsStarted(); }
private:
static std::string GetBinDir() {
Env* env = Env::Default();
std::string exe;
CHECK_OK(env->GetExecutablePath(&exe));
return DirName(exe);
}
// Tests connection to Postgres, blocking until success or it times out.
Status WaitForReady() const WARN_UNUSED_RESULT;
// 'pg_root' is the subdirectory in which the Postgres data files will live.
Status CreateConfigs();
// Directory in which to put all our stuff.
const std::string data_root_;
const std::string host_;
// Directory that has the Postgres binary.
// This may be in the thirdparty build, or may be shared across tests. As
// such, its contents should be treated as read-only.
const std::string bin_dir_;
std::unique_ptr<kudu::Subprocess> process_;
uint16_t port_ = 0;
};
} // namespace postgres
} // namespace kudu