Module: IuguLogger::SmokeTest

Defined in:
lib/iugu_logger/smoke_test.rb

Overview

Self-contained smoke test for the SDK. Verifies the consuming app’s configuration is valid AND that emit / PII redaction / canonical schema work end-to-end. Used by:

bundle exec rake iugu_logger:smoke

Output is human-readable and the run returns true on success / false on any failure. Exit code is set by the rake task wrapper.

Constant Summary collapse

CHECKS =
%i[
  sdk_loaded
  configuration_present
  basic_emit
  pii_detection
  account_id_safe_pattern
  single_line_json
].freeze

Class Method Summary collapse

Class Method Details

.blank?(value) ⇒ Boolean

Returns:

  • (Boolean)


168
169
170
# File 'lib/iugu_logger/smoke_test.rb', line 168

def blank?(value)
  value.nil? || (value.respond_to?(:empty?) && value.empty?)
end

.capture_emit(&block) ⇒ Object

─── helpers ───────────────────────────────────────────────────────────



141
142
143
144
145
146
147
148
# File 'lib/iugu_logger/smoke_test.rb', line 141

def capture_emit(&block)
  io = StringIO.new
  with_isolated_logger(io: io, format: :json, &block)
  raw = io.string.strip
  return nil if raw.empty?

  JSON.parse(raw)
end

.check_account_id_safe_patternObject



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/iugu_logger/smoke_test.rb', line 105

def 
   = 'EB450085C67C482BA652988813DAB1A5'
  payload = capture_emit do |logger|
    logger.event('iugu_logger.smoke.account_id',
                 iugu:    { account_id:  },
                 message: "smoke for account #{}")
  end

  unless payload.dig('iugu', 'account_id') == 
    return 'iugu.account_id 32-hex was modified (should be SAFE_PATTERN, ILS-002)'
  end
  unless payload['message'].to_s.include?()
    return 'account_id was redacted from message (should be SAFE_PATTERN, ILS-002)'
  end

  :ok
end

.check_basic_emitObject



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/iugu_logger/smoke_test.rb', line 74

def check_basic_emit
  payload = capture_emit do |logger|
    logger.event('iugu_logger.smoke.ok', message: 'smoke')
  end
  return 'no payload emitted' if payload.nil?
  return "missing @timestamp" if payload['@timestamp'].to_s.empty?
  return "wrong event.action: #{payload['event.action'].inspect}" if payload['event.action'] != 'iugu_logger.smoke.ok'
  return 'pii.scanned should be true' unless payload.dig('pii', 'scanned') == true

  :ok
end

.check_configuration_presentObject



65
66
67
68
69
70
71
72
# File 'lib/iugu_logger/smoke_test.rb', line 65

def check_configuration_present
  cfg = IuguLogger.configuration
  return 'service_name is blank' if blank?(cfg.service_name)
  return 'service_version is blank' if blank?(cfg.service_version)
  return 'service_environment is blank' if blank?(cfg.service_environment)

  :ok
end

.check_pii_detectionObject

v0.7+ default strategies are :detect_only for personal data. This check validates that CPF is DETECTED (so audit + tagging work) but the content is preserved (operators / fraud analysts / support need the raw value to do their jobs). For apps that need stricter redaction, override ‘c.pii_redaction = …` in the initializer.



91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/iugu_logger/smoke_test.rb', line 91

def check_pii_detection
  payload = capture_emit do |logger|
    logger.event('iugu_logger.smoke.pii', message: 'smoke for CPF 123.456.789-09')
  end

  detected = payload.dig('pii', 'detected') || []
  return "pii.detected missing 'cpf' (#{detected.inspect})" unless detected.include?('cpf')
  unless payload['message'].to_s.include?('123.456.789-09')
    return 'CPF was modified in message (expected :detect_only default)'
  end

  :ok
end

.check_sdk_loadedObject

─── checks ────────────────────────────────────────────────────────────



56
57
58
59
60
61
62
63
# File 'lib/iugu_logger/smoke_test.rb', line 56

def check_sdk_loaded
  missing = %i[Logger Pii Configuration Severity Buffer].reject do |const|
    IuguLogger.const_defined?(const)
  end
  return :ok if missing.empty?

  "missing IuguLogger::#{missing.join(', IuguLogger::')}"
end

.check_single_line_jsonObject



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/iugu_logger/smoke_test.rb', line 123

def check_single_line_json
  io = StringIO.new
  with_isolated_logger(io: io, format: :json) do |logger|
    logger.event('iugu_logger.smoke.json_line', message: 'one-liner test')
  end
  raw = io.string
  lines = raw.lines
  return "expected 1 line, got #{lines.size}" if lines.size != 1
  return 'output should end with newline' unless raw.end_with?("\n")

  JSON.parse(raw.strip)
  :ok
rescue JSON::ParserError => e
  "JSON parse failed: #{e.message}"
end

.run(io: $stdout) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/iugu_logger/smoke_test.rb', line 27

def run(io: $stdout)
  io.puts "iugu_logger #{IuguLogger::VERSION} — smoke test"
  io.puts '-' * 56

  failures = []

  CHECKS.each do |name|
    result = send("check_#{name}")
    if result == :ok
      io.puts "#{name}"
    else
      io.puts "#{name}: #{result}"
      failures << name
    end
  end

  io.puts '-' * 56

  if failures.empty?
    io.puts 'OK — all checks passed.'
    true
  else
    io.puts "FAIL — #{failures.size} check(s) failed: #{failures.join(', ')}"
    false
  end
end

.with_isolated_logger(io:, format: :json) {|IuguLogger::Logger.new(cfg)| ... } ⇒ Object

Builds an isolated Logger that mirrors the host app’s configuration but writes to ‘io` and forces JSON format. The host app’s logger and configuration are left untouched.

Yields:



153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/iugu_logger/smoke_test.rb', line 153

def with_isolated_logger(io:, format: :json)
  base = IuguLogger.configuration

  cfg = IuguLogger::Configuration.new
  cfg.service_name        = base.service_name        || 'iugu-logger-smoke'
  cfg.service_version     = base.service_version     || IuguLogger::VERSION
  cfg.service_environment = base.service_environment || 'test'
  cfg.format              = format
  cfg.output              = io
  cfg.pii_redaction       = base.pii_redaction
  cfg.pii_param_blocklist = base.pii_param_blocklist

  yield IuguLogger::Logger.new(cfg)
end