• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.adservices.shared.testing;
17 
18 import com.android.adservices.shared.testing.Logger.LogLevel;
19 
20 import com.google.common.truth.FailureMetadata;
21 
22 import java.util.Objects;
23 
24 /**
25  * Represents a call to a static method in a logging class {like @code android.util.Log or
26  * com.android.tradefed.log.LogUtil.CLog}.
27  */
28 public final class LogEntry {
29     public final LogLevel level;
30     public final String tag;
31     public final String message;
32     public final @Nullable Throwable throwable;
33 
LogEntry(LogLevel level, String tag, String message)34     public LogEntry(LogLevel level, String tag, String message) {
35         this(level, tag, message, /* throwable= */ null);
36     }
37 
LogEntry(LogLevel level, String tag, String message, @Nullable Throwable throwable)38     public LogEntry(LogLevel level, String tag, String message, @Nullable Throwable throwable) {
39         this.level = Objects.requireNonNull(level, "level cannot be null");
40         this.tag = Objects.requireNonNull(tag, "tag cannot be null");
41         this.message = Objects.requireNonNull(message, "message cannot be null");
42         this.throwable = throwable;
43     }
44 
45     @Override
hashCode()46     public int hashCode() {
47         return Objects.hash(level, message, tag, throwable);
48     }
49 
50     @Override
equals(Object obj)51     public boolean equals(Object obj) {
52         if (this == obj) return true;
53         if (obj == null) return false;
54         if (getClass() != obj.getClass()) return false;
55         LogEntry other = (LogEntry) obj;
56         return level == other.level
57                 && Objects.equals(message, other.message)
58                 && Objects.equals(tag, other.tag)
59                 && Objects.equals(throwable, other.throwable);
60     }
61 
62     @Override
toString()63     public String toString() {
64         return "LogEntry [level="
65                 + level
66                 + ", tag="
67                 + tag
68                 + ", throwable="
69                 + throwable
70                 + ", message="
71                 + message
72                 + "]";
73     }
74 
75     /**
76      * Custom {@code Truth} subject for a {@link LogEntry}.
77      *
78      * <p>Typical usage: <code>
79      * import static com.android.adservices.shared.meta_testing.LogEntry.Subject.logEntry;
80      *
81      * LogEntry entry = ...
82      * expect.withMessage("logged message")
83      * .about(logEntry())
84      * .that(entry))
85      * .hasLevel(..)
86      * .hasTag(...)
87      * .hasXyz(...);
88      * </code>
89      */
90     public static final class Subject extends com.google.common.truth.Subject {
91 
92         /** Factory method. */
logEntry()93         public static Factory<Subject, LogEntry> logEntry() {
94             return Subject::new;
95         }
96 
97         @Nullable private final LogEntry mActual;
98 
Subject(FailureMetadata metadata, @Nullable Object actual)99         private Subject(FailureMetadata metadata, @Nullable Object actual) {
100             super(metadata, actual);
101             mActual = (LogEntry) actual;
102         }
103 
104         /** Checks it has the expected level. */
hasLevel(LogLevel expected)105         public Subject hasLevel(LogLevel expected) {
106             check("level").that(mActual.level).isEqualTo(expected);
107             return this;
108         }
109 
110         /** Checks it has the expected tag. */
hasTag(String expected)111         public Subject hasTag(String expected) {
112             check("tag").that(mActual.tag).isEqualTo(expected);
113             return this;
114         }
115 
116         /** Checks it has the expected throwable. */
hasThrowable(Throwable expected)117         public Subject hasThrowable(Throwable expected) {
118             check("throwable").that(mActual.throwable).isSameInstanceAs(expected);
119             return this;
120         }
121 
122         /** Checks it has the expected message. */
hasMessage(String expected)123         public Subject hasMessage(String expected) {
124             check("message").that(mActual.message).isEqualTo(expected);
125             return this;
126         }
127     }
128 }
129