LCOV - code coverage report
Current view: top level - frontend/handlers - query_test_fixture.h (source / functions) Coverage Total Hit
Test: _coverage_report.dat Lines: 96.4 % 84 81
Test Date: 2026-07-02 21:01:18 Functions: 100.0 % 10 10

            Line data    Source code
       1              : #ifndef BIGQUERY_EMULATOR_FRONTEND_HANDLERS_QUERY_TEST_FIXTURE_H_
       2              : #define BIGQUERY_EMULATOR_FRONTEND_HANDLERS_QUERY_TEST_FIXTURE_H_
       3              : 
       4              : #include <cstdint>
       5              : #include <cstdlib>
       6              : #include <filesystem>
       7              : #include <functional>
       8              : #include <memory>
       9              : #include <random>
      10              : #include <string>
      11              : #include <system_error>
      12              : #include <utility>
      13              : #include <vector>
      14              : 
      15              : #include "absl/strings/str_cat.h"
      16              : #include "absl/strings/string_view.h"
      17              : #include "absl/types/span.h"
      18              : #include "backend/engine/coordinator/local_coordinator_engine.h"
      19              : #include "backend/schema/schema.h"
      20              : #include "backend/storage/duckdb/duckdb_storage.h"
      21              : #include "backend/storage/storage.h"
      22              : #include "frontend/handlers/query.h"
      23              : #include "grpcpp/grpcpp.h"
      24              : #include "gtest/gtest.h"
      25              : #include "proto/emulator.pb.h"
      26              : 
      27              : namespace bigquery_emulator {
      28              : namespace frontend {
      29              : 
      30              : namespace fs = std::filesystem;
      31              : 
      32              : class QueryServiceTest : public ::testing::Test {
      33              :  protected:
      34           20 :   void SetUp() override {
      35           20 :     const char* tmpdir_env = std::getenv("TMPDIR");
      36           20 :     const std::string tmpdir = tmpdir_env != nullptr ? tmpdir_env : "/tmp";
      37           20 :     std::random_device rd;
      38           20 :     std::seed_seq seed{rd(), rd()};
      39           20 :     std::mt19937_64 rng(seed);
      40           20 :     data_dir_ = fs::path(tmpdir) / absl::StrCat("bqemu-query-test-", rng());
      41           20 :     std::error_code ec;
      42           20 :     fs::remove_all(data_dir_, ec);
      43           20 :     auto opened =
      44           20 :         backend::storage::duckdb::DuckDBStorage::Open(data_dir_.string());
      45           40 :     ASSERT_TRUE(opened.ok()) << opened.status();
      46           20 :     storage_ = std::move(opened).value();
      47           20 :     engine_ =
      48           20 :         std::make_unique<backend::engine::coordinator::LocalCoordinatorEngine>(
      49           20 :             storage_.get());
      50           20 :     service_ = std::make_unique<QueryService>(storage_.get(), engine_.get());
      51           20 :   }
      52              : 
      53           20 :   void TearDown() override {
      54           20 :     service_.reset();
      55           20 :     engine_.reset();
      56           20 :     storage_.reset();
      57           20 :     std::error_code ec;
      58           20 :     fs::remove_all(data_dir_, ec);
      59           20 :   }
      60              : 
      61           19 :   v1::QueryRequest MakeRequest(absl::string_view sql) {
      62           19 :     v1::QueryRequest req;
      63           19 :     req.set_project_id("proj-test");
      64           19 :     req.set_sql(std::string(sql));
      65           19 :     return req;
      66           19 :   }
      67              : 
      68            5 :   void CreatePeopleTable() {
      69            5 :     backend::schema::TableSchema schema;
      70            5 :     backend::schema::ColumnSchema id;
      71            5 :     id.name = "id";
      72            5 :     id.type = backend::schema::ColumnType::kInt64;
      73            5 :     id.mode = backend::schema::ColumnMode::kRequired;
      74            5 :     schema.columns.push_back(id);
      75            5 :     backend::schema::ColumnSchema name;
      76            5 :     name.name = "name";
      77            5 :     name.type = backend::schema::ColumnType::kString;
      78            5 :     name.mode = backend::schema::ColumnMode::kNullable;
      79            5 :     schema.columns.push_back(name);
      80            5 :     backend::schema::ColumnSchema tags;
      81            5 :     tags.name = "tags";
      82            5 :     tags.type = backend::schema::ColumnType::kString;
      83            5 :     tags.mode = backend::schema::ColumnMode::kRepeated;
      84            5 :     schema.columns.push_back(tags);
      85            5 :     ASSERT_TRUE(storage_->CreateDataset({"proj-test", "ds"}, "US").ok());
      86            5 :     ASSERT_TRUE(storage_->CreateTable({"proj-test", "ds", "t"}, schema).ok());
      87            5 :   }
      88              : 
      89              :   fs::path data_dir_{};
      90              :   std::unique_ptr<backend::storage::duckdb::DuckDBStorage> storage_{};
      91              :   std::unique_ptr<backend::engine::coordinator::LocalCoordinatorEngine>
      92              :       engine_{};
      93              :   std::unique_ptr<QueryService> service_{};
      94              : };
      95              : 
      96              : class MessageCollector {
      97              :  public:
      98           12 :   std::function<bool(const v1::QueryResultRow&)> Writer() {
      99           35 :     return [this](const v1::QueryResultRow& msg) {
     100           35 :       messages_.push_back(msg);
     101           35 :       return true;
     102           35 :     };
     103           12 :   }
     104           10 :   const std::vector<v1::QueryResultRow>& messages() const {
     105           10 :     return messages_;
     106           10 :   }
     107              : 
     108            6 :   const v1::QueryResultRow* PhaseTimingsTrailer() const {
     109           18 :     for (auto it = messages_.rbegin(); it != messages_.rend(); ++it) {
     110           18 :       if (it->has_phase_timings() && !it->phase_timings().phases().empty()) {
     111            6 :         return &(*it);
     112            6 :       }
     113           18 :     }
     114            0 :     return nullptr;
     115            6 :   }
     116              : 
     117            6 :   const v1::QueryResultRow* StatementTypeTrailer() const {
     118           12 :     for (auto it = messages_.rbegin(); it != messages_.rend(); ++it) {
     119           12 :       if (!it->statement_type().empty()) {
     120            6 :         return &(*it);
     121            6 :       }
     122           12 :     }
     123            0 :     return nullptr;
     124            6 :   }
     125              : 
     126            6 :   const v1::QueryResultRow* EmulatorRouteTrailer() const {
     127            6 :     for (auto it = messages_.rbegin(); it != messages_.rend(); ++it) {
     128            6 :       if (!it->emulator_route().empty()) {
     129            6 :         return &(*it);
     130            6 :       }
     131            6 :     }
     132            0 :     return nullptr;
     133            6 :   }
     134              : 
     135              :  private:
     136              :   std::vector<v1::QueryResultRow> messages_{};
     137              : };
     138              : 
     139              : }  // namespace frontend
     140              : }  // namespace bigquery_emulator
     141              : 
     142              : #endif  // BIGQUERY_EMULATOR_FRONTEND_HANDLERS_QUERY_TEST_FIXTURE_H_
        

Generated by: LCOV version 2.0-1