Context.java

1
package com.renomad.minum.state;
2
3
import com.renomad.minum.database.Db;
4
import com.renomad.minum.database.DbData;
5
import com.renomad.minum.database.DbEngine2;
6
import com.renomad.minum.logging.ILogger;
7
import com.renomad.minum.queue.ActionQueueState;
8
import com.renomad.minum.web.FullSystem;
9
10
import java.nio.file.Path;
11
import java.util.HashSet;
12
import java.util.Set;
13
import java.util.concurrent.ExecutorService;
14
import java.util.concurrent.locks.ReentrantLock;
15
16
17
/**
18
 * Holds important system-wide data and methods, such as the
19
 * logger, constants, and the {@link FullSystem} instance.
20
 * <p>
21
 *     The common situations:
22
 * </p>
23
 * <ul>
24
 *     <li>Building a Minum {@link Db} database</li>
25
 *     <li>Getting system constants like the database directory</li>
26
 *     <li>Getting the system {@link ExecutorService} for starting threads or an {@link com.renomad.minum.queue.ActionQueue}</li>
27
 *     <li>Getting a {@link FullSystem} object, which has
28
 *     <ul>
29
 *         <li>the {@link com.renomad.minum.web.WebFramework}, which registers endpoints</li>
30
 *         <li>the {@link com.renomad.minum.security.TheBrig}, which handles bad actors on the internet</li>
31
 *     </ul>
32
 *     </li>
33
 * </ul>
34
 */
35
public final class Context {
36
37
    private final ILogger logger;
38
    private final ExecutorService executorService;
39
    private final Constants constants;
40
    private FullSystem fullSystem;
41
    private final ActionQueueState actionQueueState;
42
43
    /**
44
     * A record of which paths are registered for database
45
     * use, to prevent multiple databases unknowingly pointing
46
     * to the same directory.
47
     */
48
    private final Set<Path> registeredDatabasePaths;
49
50
    /**
51
     * Used to provide thread-safe access to the {@link #registeredDatabasePaths}
52
     */
53
    private final ReentrantLock databasePathsLock;
54
55
    public Context(ExecutorService executorService, Constants constants, ILogger logger) {
56
        this.executorService = executorService;
57
        this.constants = constants;
58
        actionQueueState = new ActionQueueState();
59
        this.logger = logger;
60
        this.registeredDatabasePaths = new HashSet<>();
61
        this.databasePathsLock = new ReentrantLock();
62
    }
63
64
    public ILogger getLogger() {
65 1 1. getLogger : replaced return value with null for com/renomad/minum/state/Context::getLogger → KILLED
        return logger;
66
    }
67
68
    public ExecutorService getExecutorService() {
69 1 1. getExecutorService : replaced return value with null for com/renomad/minum/state/Context::getExecutorService → KILLED
        return executorService;
70
    }
71
72
    public Constants getConstants() {
73 1 1. getConstants : replaced return value with null for com/renomad/minum/state/Context::getConstants → KILLED
        return constants;
74
    }
75
76
    public void setFullSystem(FullSystem fullSystem) {
77
        this.fullSystem = fullSystem;
78
    }
79
80
    public FullSystem getFullSystem() {
81 1 1. getFullSystem : replaced return value with null for com/renomad/minum/state/Context::getFullSystem → TIMED_OUT
        return fullSystem;
82
    }
83
84
    public ActionQueueState getActionQueueState() {
85 1 1. getActionQueueState : replaced return value with null for com/renomad/minum/state/Context::getActionQueueState → KILLED
        return actionQueueState;
86
    }
87
88
    /**
89
     * This is a helper method to instantiate a {@link Db} class,
90
     * avoiding the need for a user to provide the root database
91
     * directory and the context.
92
     * <p>
93
     * Since this is a generic method, a bit of care is required when
94
     * calling.  Try to use a pattern like the following pseudocode:
95
     * {@snippet :
96
     *  Db<Photograph> photoDb = context.getDb("photos", new Photograph());
97
     * }
98
     * @param name the name of this data.  Note that this will be used
99
     *             as the directory for the data, so use characters your
100
     *             operating system would allow.
101
     * @param instance an instance of the {@link DbData} data. This is used in the
102
     *                 Db code to deserialize the data when reading.
103
     */
104
    public <T extends DbData<?>> Db<T> getDb(String name, T instance) {
105 1 1. getDb : replaced return value with null for com/renomad/minum/state/Context::getDb → KILLED
        return new Db<>(Path.of(constants.dbDirectory, name), this, instance);
106
    }
107
108
    /**
109
     * This is a helper method to instantiate a {@link DbEngine2} class,
110
     * using the engine2 database implementation. It is similar to
111
     * {@link #getDb(String, DbData)} in all other respects.
112
     * <p>
113
     *     By switching your old database calls to use this, when it runs
114
     *     it will convert the file schema.
115
     * </p>
116
     * <p>
117
     *     <b>Please backup your database before conversion</b>
118
     * </p>
119
     */
120
    public <T extends DbData<?>> DbEngine2<T> getDb2(String name, T instance) {
121 1 1. getDb2 : replaced return value with null for com/renomad/minum/state/Context::getDb2 → KILLED
        return new DbEngine2<>(Path.of(constants.dbDirectory, name), this, instance);
122
    }
123
124
125
    /* ***********************************************
126
127
    Database path registrations
128
129
    This next section includes some methods for managing
130
    the set of registered database paths in use by
131
    the system
132
133
     *********************************************** */
134
135
    /**
136
     * Return true if the input path exists in the set
137
     */
138
    public boolean isDbPathRegistered(Path path) {
139 2 1. isDbPathRegistered : replaced boolean return with true for com/renomad/minum/state/Context::isDbPathRegistered → KILLED
2. isDbPathRegistered : replaced boolean return with false for com/renomad/minum/state/Context::isDbPathRegistered → KILLED
        return this.registeredDatabasePaths.contains(path);
140
    }
141
142
    /**
143
     * Add a path to the set of paths we are tracking as
144
     * registered for a database.  This is used to prevent
145
     * pointing two databases at the same directory, which
146
     * would lead to data corruption.
147
     */
148
    public void addToDbPaths(Path path) {
149 1 1. addToDbPaths : removed call to java/util/concurrent/locks/ReentrantLock::lock → KILLED
        this.databasePathsLock.lock();
150
        try {
151
            logger.logDebug(() -> "Adding registration for database path " + path);
152
            this.registeredDatabasePaths.add(path);
153
        } finally {
154 1 1. addToDbPaths : removed call to java/util/concurrent/locks/ReentrantLock::unlock → KILLED
            this.databasePathsLock.unlock();
155
        }
156
    }
157
158
159
    /**
160
     * Remove an item from the set of registered database paths,
161
     * run when a database shuts down.
162
     */
163
    public void removeFromPaths(Path path) {
164 1 1. removeFromPaths : removed call to java/util/concurrent/locks/ReentrantLock::lock → KILLED
        this.databasePathsLock.lock();
165
        try {
166
            logger.logDebug(() -> "Removing registration for database path " + path);
167
            this.registeredDatabasePaths.remove(path);
168
        } finally {
169 1 1. removeFromPaths : removed call to java/util/concurrent/locks/ReentrantLock::unlock → KILLED
            this.databasePathsLock.unlock();
170
        }
171
    }
172
173
    /**
174
     * Remove all registered paths from the set, mostly
175
     * used when testing
176
     */
177
    public void clearDatabasePaths() {
178 1 1. clearDatabasePaths : removed call to java/util/concurrent/locks/ReentrantLock::lock → TIMED_OUT
        this.databasePathsLock.lock();
179
        try {
180
            logger.logDebug(() -> "Removing all registered database paths: " + registeredDatabasePaths);
181 1 1. clearDatabasePaths : removed call to java/util/Set::clear → KILLED
            this.registeredDatabasePaths.clear();
182
        } finally {
183 1 1. clearDatabasePaths : removed call to java/util/concurrent/locks/ReentrantLock::unlock → TIMED_OUT
            this.databasePathsLock.unlock();
184
        }
185
    }
186
187
}

Mutations

65

1.1
Location : getLogger
Killed by : com.renomad.minum.web.FunctionalTestingTests.test_sendDealsWithException(com.renomad.minum.web.FunctionalTestingTests)
replaced return value with null for com/renomad/minum/state/Context::getLogger → KILLED

69

1.1
Location : getExecutorService
Killed by : com.renomad.minum.web.FunctionalTestingTests.test_sendDealsWithException(com.renomad.minum.web.FunctionalTestingTests)
replaced return value with null for com/renomad/minum/state/Context::getExecutorService → KILLED

73

1.1
Location : getConstants
Killed by : com.renomad.minum.web.FunctionalTestingTests.test_sendDealsWithException(com.renomad.minum.web.FunctionalTestingTests)
replaced return value with null for com/renomad/minum/state/Context::getConstants → KILLED

81

1.1
Location : getFullSystem
Killed by : none
replaced return value with null for com/renomad/minum/state/Context::getFullSystem → TIMED_OUT

85

1.1
Location : getActionQueueState
Killed by : com.renomad.minum.web.FunctionalTestingTests.test_sendDealsWithException(com.renomad.minum.web.FunctionalTestingTests)
replaced return value with null for com/renomad/minum/state/Context::getActionQueueState → KILLED

105

1.1
Location : getDb
Killed by : com.renomad.minum.FunctionalTests.test_EdgeCase_IOExceptionThrown_WebFramework(com.renomad.minum.FunctionalTests)
replaced return value with null for com/renomad/minum/state/Context::getDb → KILLED

121

1.1
Location : getDb2
Killed by : com.renomad.minum.web.WebPerformanceTests.webPerfTest(com.renomad.minum.web.WebPerformanceTests)
replaced return value with null for com/renomad/minum/state/Context::getDb2 → KILLED

139

1.1
Location : isDbPathRegistered
Killed by : com.renomad.minum.utils.ActionQueueKillerTests
replaced boolean return with true for com/renomad/minum/state/Context::isDbPathRegistered → KILLED

2.2
Location : isDbPathRegistered
Killed by : com.renomad.minum.web.WebPerformanceTests.webPerfTest(com.renomad.minum.web.WebPerformanceTests)
replaced boolean return with false for com/renomad/minum/state/Context::isDbPathRegistered → KILLED

149

1.1
Location : addToDbPaths
Killed by : com.renomad.minum.utils.ActionQueueKillerTests
removed call to java/util/concurrent/locks/ReentrantLock::lock → KILLED

154

1.1
Location : addToDbPaths
Killed by : com.renomad.minum.web.WebPerformanceTests.webPerfTest(com.renomad.minum.web.WebPerformanceTests)
removed call to java/util/concurrent/locks/ReentrantLock::unlock → KILLED

164

1.1
Location : removeFromPaths
Killed by : com.renomad.minum.security.TheBrigTests
removed call to java/util/concurrent/locks/ReentrantLock::lock → KILLED

169

1.1
Location : removeFromPaths
Killed by : com.renomad.minum.security.TheBrigTests
removed call to java/util/concurrent/locks/ReentrantLock::unlock → KILLED

178

1.1
Location : clearDatabasePaths
Killed by : none
removed call to java/util/concurrent/locks/ReentrantLock::lock → TIMED_OUT

181

1.1
Location : clearDatabasePaths
Killed by : com.renomad.minum.security.TheBrigTests
removed call to java/util/Set::clear → KILLED

183

1.1
Location : clearDatabasePaths
Killed by : none
removed call to java/util/concurrent/locks/ReentrantLock::unlock → TIMED_OUT

Active mutators

Tests examined


Report generated by PIT 1.17.0