Coverage Report

Created: 2026-07-25 06:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/action_validation_fuzzer.cc
Line
Count
Source
1
// Copyright 2026 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
//
15
//##############################################################################
16
17
#include <stdint.h>
18
#include <stddef.h>
19
#include <memory>
20
#include <utility>
21
22
#include "action_validation.h"
23
#include "daemon_context.h"
24
#include "scheduler_interface.h"
25
#include "persistent_storage.h"
26
#include "safepower_agent.pb.h"
27
#include "safepower_agent_config.pb.h"
28
#include "system_state.pb.h"
29
#include "absl/time/time.h"
30
#include "absl/status/status.h"
31
#include "absl/status/statusor.h"
32
33
namespace safepower_agent {
34
35
class DummyScheduler : public SchedulerInterface {
36
 public:
37
  absl::Status PeriodicCall(absl::AnyInvocable<void()> fn,
38
                            absl::Duration interval,
39
0
                            absl::string_view name) override {
40
0
    return absl::OkStatus();
41
0
  }
42
  absl::Status DelayCall(absl::AnyInvocable<void() &&> fn,
43
                         absl::Duration wait_duration,
44
0
                         absl::string_view name) override {
45
0
    return absl::OkStatus();
46
0
  }
47
0
  absl::Status CancelCall(absl::string_view name) override {
48
0
    return absl::OkStatus();
49
0
  }
50
0
  absl::Status CancelAll() override {
51
0
    return absl::OkStatus();
52
0
  }
53
0
  absl::Status Shutdown() override {
54
0
    return absl::OkStatus();
55
0
  }
56
};
57
58
class DummyPersistentStorage : public PersistentStorageManager {
59
 public:
60
  absl::Status WriteSavedActionsChange(
61
0
      const safepower_agent_persistence_proto::SavedActions& actions) override {
62
0
    return absl::OkStatus();
63
0
  }
64
  absl::StatusOr<safepower_agent_persistence_proto::SavedActions>
65
0
  ReadSavedActions() override {
66
0
    return safepower_agent_persistence_proto::SavedActions();
67
0
  }
68
0
  absl::Status InitializeSavedActions() override {
69
0
    return absl::OkStatus();
70
0
  }
71
};
72
73
class DummyDaemonContext : public DaemonContext {
74
 public:
75
1
  DummyDaemonContext() : scheduler_(), storage_() {}
76
  
77
0
  uint64_t epoch_ms() override { return 0; }
78
0
  SchedulerInterface& scheduler() override { return scheduler_; }
79
0
  PersistentStorageManager& persistent_storage_manager() override { return storage_; }
80
0
  absl::StatusOr<safepower_agent_proto::BuildInfo> GetBuildInfo() const override {
81
0
    return safepower_agent_proto::BuildInfo();
82
0
  }
83
84
 private:
85
  DummyScheduler scheduler_;
86
  DummyPersistentStorage storage_;
87
};
88
89
}  // namespace safepower_agent
90
91
13.1k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
92
13.1k
  static safepower_agent::DummyDaemonContext* context = new safepower_agent::DummyDaemonContext();
93
94
13.1k
  if (size < 4) return 0;
95
  // Use first 2 bytes for size of request
96
13.1k
  uint16_t req_size = (data[0] << 8) | data[1];
97
13.1k
  if (req_size > size - 2) return 0;
98
  
99
13.1k
  safepower_agent_proto::StartActionRequest request;
100
13.1k
  if (!request.ParseFromArray(data + 2, req_size)) {
101
2.92k
    return 0;
102
2.92k
  }
103
  
104
10.2k
  safepower_agent_proto::SystemState initial_system_state;
105
10.2k
  if (!initial_system_state.ParseFromArray(data + 2 + req_size, size - 2 - req_size)) {
106
4.82k
    return 0;
107
4.82k
  }
108
  
109
5.43k
  absl::Time start_time = absl::FromUnixSeconds(1234567890);
110
5.43k
  safepower_agent_config::ConditionValidationOptions options;
111
5.43k
  options.set_max_boots(10);
112
5.43k
  options.set_max_timeout_seconds(3600);
113
5.43k
  std::string node_entity_tag = "node-1";
114
5.43k
  if (!initial_system_state.node_state().empty()) {
115
3.10k
    node_entity_tag = initial_system_state.node_state().begin()->first;
116
3.10k
  }
117
118
5.43k
  safepower_agent::ValidateRequest(request, node_entity_tag, initial_system_state, start_time, options);
119
5.43k
  return 0;
120
10.2k
}