Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(maint) Add flexibility to logged? to not only match a single line #314

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/clojure-linting.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Clojure Linting

on:
pull_request:
types: [opened, reopened, edited, synchronize]
paths: ['src/**','test/**','.clj-kondo/config.edn','project.clj','.github/**']

jobs:
clojure-linting:
name: Clojure Linting
runs-on: ubuntu-latest
steps:
- name: setup java
uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 17
- name: checkout repo
uses: actions/checkout@v2
- name: install clj-kondo (this is quite fast)
run: |
curl -sLO https://raw.githubusercontent.com/clj-kondo/clj-kondo/master/script/install-clj-kondo
chmod +x install-clj-kondo
./install-clj-kondo --dir .
- name: kondo lint
run: ./clj-kondo --lint src test
- name: eastwood lint
run: |
java -version
lein eastwood
29 changes: 29 additions & 0 deletions .github/workflows/lein-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: PR Testing

on:
workflow_dispatch:
pull_request:
types: [opened, reopened, edited, synchronize]
paths: ['src/**','test/**','project.clj']

jobs:
pr-testing:
name: PR Testing
strategy:
fail-fast: false
matrix:
version: ['8', '11', '17']
runs-on: ubuntu-latest
steps:
- name: checkout repo
uses: actions/checkout@v3
with:
submodules: recursive
- name: setup java
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: ${{ matrix.version }}
- name: clojure tests
run: lein test
timeout-minutes: 30
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 3.3.2
* this is a minor release changing a test utility
* adds a new arity to `logged?` that removes the restriction that only one log line must match the pattern, adds printing to the function and repo documentation to make users aware of this single line match restriction

## 3.3.1

This is a minor dependency change release
Expand Down
8 changes: 6 additions & 2 deletions documentation/Test-Utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,15 @@ since the beginning of the form.
See the `logged?` docstring for a complete description, but as an
example, if the first argument is a regex pattern (typically generated
via Clojure's `#"pattern"`), then `logged?` will return true if the
pattern matches the message of anything that has been logged since the
beginning of the enclosing `with-test-logging` form. An optional
pattern matches a single message of anything that has been logged since the
beginning of the enclosing `with-test-logging` form. An optional
second parameter restricts the match to log events with the specified
level: `:trace`, `:debug`, `:info`, `:warn`, `:error` or `:fatal`.

Note: by default `logged?` returns true only if there is exactly one
log line match. An optional third parameter can be specified to disable
this restriction.

### `event->map`

This function converts a LogEvent to a Clojure map of the kind
Expand Down
17 changes: 17 additions & 0 deletions test/puppetlabs/trapperkeeper/logging_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,23 @@
(is (true? @done?))
(is (logged? #"test thread" :info))))))

(deftest with-test-logging-and-duplicate-log-lines
(testing "test-logging captures matches duplicate lines when specified"
(with-test-logging
(log/error "duplicate message")
(log/error "duplicate message")
(log/warn "duplicate message")
(log/warn "single message")
(testing "single line only match"
(is (not (logged? #"duplicate message"))) ;; original behavior of the fn, default behavior
(is (logged? #"duplicate message" :warn false)))
(testing "disabling single line match, enabling multiple line match"
(is (logged? #"duplicate message" :error true))
(is (logged? #"duplicate message" nil true))
(testing "still handles single matches"
(is (logged? #"single message" nil true))
(is (logged? #"single message" :warn true)))))))

(deftest test-logging-configuration
(testing "Calling `configure-logging!` with a logback.xml file"
(configure-logging! "./dev-resources/logging/logback-debug.xml")
Expand Down
18 changes: 11 additions & 7 deletions test/puppetlabs/trapperkeeper/testutils/logging.clj
Original file line number Diff line number Diff line change
Expand Up @@ -319,20 +319,24 @@
~@body)))))

(s/defn ^{:always-validate true} logged?
([msg-or-pred] (logged? msg-or-pred nil))
([msg-or-pred] (logged? msg-or-pred nil nil))
([msg-or-pred maybe-level] (logged? msg-or-pred maybe-level nil))
([msg-or-pred :- (s/conditional ifn? (s/pred ifn?)
string? s/Str
:else Pattern)
maybe-level :- (s/maybe (s/pred #(levels %)))]
maybe-level :- (s/maybe (s/pred #(levels %)))
disable-single-line-match-restriction :- (s/maybe s/Bool)]
(let [match? (cond (ifn? msg-or-pred) msg-or-pred
(string? msg-or-pred) #(= msg-or-pred (:message %))
:else #(re-find msg-or-pred (:message %)))
one-element? #(and (seq %) (empty? (rest %)))
one-element-if-specified? #(if (and (seq %) (or disable-single-line-match-restriction (empty? (rest %))))
true
(println "\n`logged?` warning: multiple log line matches found, but this arity expects only one match, returning false. Found matches: " % "\n"))
correct-level? #(or (nil? maybe-level) (= maybe-level (:level %)))]
(->> (map event->map @*test-log-events*)
(filter correct-level?)
(filter match?)
(one-element?)))))
(one-element-if-specified?)))))

(defmethod clojure.test/assert-expr 'logged? [is-msg form]
"Asserts that exactly one event in *test-log-events* has a message
Expand All @@ -342,10 +346,10 @@
is specified, the message's keyword level (:info, :error, etc.) must
also match. For example:
(with-test-logging (log/info \"123\") (is (logged? #\"2\")))."
(assert (#{2 3} (count form)))
(let [[_ msg-or-pred level] form]
(assert (#{2 3 4} (count form)))
(let [[_ msg-or-pred level disable-single-line-restriction] form]
`(let [events# @@#'puppetlabs.trapperkeeper.testutils.logging/*test-log-events*]
(if-not (logged? ~msg-or-pred ~level)
(if-not (logged? ~msg-or-pred ~level ~disable-single-line-restriction)
(clojure.test/do-report
{:type :fail
:message ~is-msg
Expand Down
2 changes: 1 addition & 1 deletion test/puppetlabs/trapperkeeper/testutils/logging_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[clojure.tools.logging :as log]
[puppetlabs.kitchensink.core :as kitchensink]
[puppetlabs.trapperkeeper.logging :refer [reset-logging root-logger-name]]
[puppetlabs.trapperkeeper.testutils.logging :as tgt :refer [event->map]])
[puppetlabs.trapperkeeper.testutils.logging :as tgt :refer [event->map logged?]])
(:import
(org.slf4j LoggerFactory)))

Expand Down
Loading