< Summary - Backend C Tests - Coverage Report

Information
Class: test_sensor_service_c
Assembly: src.backend.tests.unit.database
File(s): C:\Users\yagiz\Desktop\Project\smart-maintenance-suite\src\backend\tests\unit\database\test_sensor_service.c
Line coverage
95%
Covered lines: 115
Uncovered lines: 6
Coverable lines: 121
Total lines: 240
Line coverage: 95%
Branch coverage
65%
Covered branches: 26
Total branches: 40
Branch coverage: 65%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
reset_mocks100%00100%
db_pool_acquire100%00100%
db_pool_release100%00100%
check_and_trigger_alerts100%00100%
test_connection_failure50%00100%
test_query_failure50%00100%
test_zero_rows50%00100%
test_successful_fetch50%00100%
test_truncate_rows50%00100%
test_insert_connection_fail50%00100%
test_insert_query_fail50%00100%
test_insert_success_alert_called50%00100%
main100%00100%

File(s)

C:\Users\yagiz\Desktop\Project\smart-maintenance-suite\src\backend\tests\unit\database\test_sensor_service.c

#LineLine coverage
 1#define _GNU_SOURCE
 2#include <stdio.h>
 3#include <string.h>
 4#include <assert.h>
 5#include <stdlib.h>
 6
 7#include <libpq-fe.h>          // GERÇEK libpq header
 8#include "sensor_service.h"    // Senin servis
 9
 10/* ==========================================================
 11   GLOBAL MOCK STATE
 12   ========================================================== */
 13
 14static int mock_db_available;
 15static int mock_query_success;
 16static int mock_rows;
 17static int mock_alert_called;
 18static int last_query_type;   /* 1=SELECT, 2=INSERT */
 19
 20/* ==========================================================
 21   RESET
 22   ========================================================== */
 23
 824void reset_mocks() {
 825  mock_db_available = 1;
 826  mock_query_success = 1;
 827  mock_rows = 1;
 828  mock_alert_called = 0;
 829  last_query_type = 0;
 830}
 31
 32/* ==========================================================
 33   FAKE DB CONNECTION
 34   ========================================================== */
 35
 36typedef struct {
 37  PGconn *pg_conn;
 38} DBConnection;
 39
 40static DBConnection fake_conn;
 41static PGresult *fake_res = (PGresult *)0x1;
 42/* ==========================================================
 43   MOCK DB POOL
 44   ========================================================== */
 45
 846DBConnection *db_pool_acquire() {
 847  if (!mock_db_available)
 248    return NULL;
 49
 650  return &fake_conn;
 51}
 52
 653void db_pool_release(DBConnection *conn) {
 54  (void)conn;
 655}
 56
 57/* ==========================================================
 58   MOCK LIBPQ FUNCTIONS
 59   ========================================================== */
 60
 61PGresult *PQexec(PGconn *conn, const char *query) {
 62  (void)conn;
 63
 664  if (strstr(query, "SELECT"))
 465    last_query_type = 1;
 266  else if (strstr(query, "INSERT"))
 267    last_query_type = 2;
 68  else
 069    last_query_type = 0;
 70
 671  return fake_res;
 72}
 73
 74ExecStatusType PQresultStatus(const PGresult *res) {
 75  (void)res;
 76
 677  if (!mock_query_success)
 278    return PGRES_FATAL_ERROR;
 79
 480  if (last_query_type == 1)
 381    return PGRES_TUPLES_OK;
 82
 183  if (last_query_type == 2)
 184    return PGRES_COMMAND_OK;
 85
 086  return PGRES_FATAL_ERROR;
 87}
 88
 89int PQntuples(const PGresult *res) {
 90  (void)res;
 391  return mock_rows;
 92}
 93
 94char *PQgetvalue(const PGresult *res, int row, int col) {
 95  (void)res;
 96  (void)row;
 97  static char buffer[64];
 98
 1599  switch (col) {
 3100    case 0:
 3101      strcpy(buffer, "101");
 3102      break;
 103
 3104    case 1:
 3105      strcpy(buffer, "Temperature");
 3106      break;
 107
 3108    case 2:
 3109      strcpy(buffer, "42.5");
 3110      break;
 111
 3112    case 3:
 3113      strcpy(buffer, "C");
 3114      break;
 115
 3116    case 4:
 3117      strcpy(buffer, "2025-01-01 12:00:00");
 3118      break;
 119
 0120    default:
 0121      strcpy(buffer, "");
 0122      break;
 123  }
 124
 15125  return buffer;
 126}
 127
 128void PQclear(PGresult *res) {
 129  (void)res;
 6130}
 131
 132char *PQerrorMessage(const PGconn *conn) {
 133  (void)conn;
 0134  return "Mock error";
 135}
 136
 137/* ==========================================================
 138   MOCK ALERT
 139   ========================================================== */
 140
 1141void check_and_trigger_alerts(int sensor_id,
 142                              const char *sensor_type,
 143                              double value) {
 144  (void)sensor_id;
 145  (void)sensor_type;
 146  (void)value;
 1147  mock_alert_called = 1;
 1148}
 149
 150/* ==========================================================
 151   TESTS
 152   ========================================================== */
 153
 1154void test_connection_failure() {
 1155  reset_mocks();
 1156  mock_db_available = 0;
 157  SensorStatus stats[5];
 1158  int result = get_machine_sensor_stats(1, stats, 5);
 1159  assert(result == 0);
 1160  printf("✔ test_connection_failure\n");
 1161}
 162
 1163void test_query_failure() {
 1164  reset_mocks();
 1165  mock_query_success = 0;
 166  SensorStatus stats[5];
 1167  int result = get_machine_sensor_stats(1, stats, 5);
 1168  assert(result == 0);
 1169  printf("✔ test_query_failure\n");
 1170}
 171
 1172void test_zero_rows() {
 1173  reset_mocks();
 1174  mock_rows = 0;
 175  SensorStatus stats[5];
 1176  int result = get_machine_sensor_stats(1, stats, 5);
 1177  assert(result == 0);
 1178  printf("✔ test_zero_rows\n");
 1179}
 180
 1181void test_successful_fetch() {
 1182  reset_mocks();
 1183  mock_rows = 1;
 184  SensorStatus stats[5];
 1185  int result = get_machine_sensor_stats(1, stats, 5);
 1186  assert(result == 1);
 1187  assert(stats[0].sensor_id == 101);
 1188  assert(strcmp(stats[0].sensor_type, "Temperature") == 0);
 1189  printf("✔ test_successful_fetch\n");
 1190}
 191
 1192void test_truncate_rows() {
 1193  reset_mocks();
 1194  mock_rows = 10;
 195  SensorStatus stats[2];
 1196  int result = get_machine_sensor_stats(1, stats, 2);
 1197  assert(result == 2);
 1198  printf("✔ test_truncate_rows\n");
 1199}
 200
 1201void test_insert_connection_fail() {
 1202  reset_mocks();
 1203  mock_db_available = 0;
 1204  int result = add_sensor_reading(1, "Temperature", 50.0);
 1205  assert(result == 0);
 1206  printf("✔ test_insert_connection_fail\n");
 1207}
 208
 1209void test_insert_query_fail() {
 1210  reset_mocks();
 1211  mock_query_success = 0;
 1212  int result = add_sensor_reading(1, "Temperature", 50.0);
 1213  assert(result == 0);
 1214  printf("✔ test_insert_query_fail\n");
 1215}
 216
 1217void test_insert_success_alert_called() {
 1218  reset_mocks();
 1219  int result = add_sensor_reading(1, "Temperature", 50.0);
 1220  assert(result == 1);
 1221  assert(mock_alert_called == 1);
 1222  printf("✔ test_insert_success_alert_called\n");
 1223}
 224
 225/* ==========================================================
 226   MAIN
 227   ========================================================== */
 228
 1229int main() {
 1230  test_connection_failure();
 1231  test_query_failure();
 1232  test_zero_rows();
 1233  test_successful_fetch();
 1234  test_truncate_rows();
 1235  test_insert_connection_fail();
 1236  test_insert_query_fail();
 1237  test_insert_success_alert_called();
 1238  printf("\nAll sensor_service tests passed.\n");
 1239  return 0;
 240}