summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarsten Loesing <karsten.loesing@gmx.net>2019-08-14 08:51:29 +0200
committerKarsten Loesing <karsten.loesing@gmx.net>2019-08-14 09:54:56 +0200
commitcd5a27d3495f2cd8fd7c693e20a406f571d36a2f (patch)
tree2d7d19889d02f9d33e2c3f9a6b79b0d95f3c5029
parent027a54bfe2c970a72db2afc485d2fa12f77cb247 (diff)
Archive snowflake statistics.
Implements #29461.
-rw-r--r--CHANGELOG.md1
-rw-r--r--build.xml2
-rw-r--r--src/main/java/org/torproject/metrics/collector/Main.java3
-rw-r--r--src/main/java/org/torproject/metrics/collector/conf/Annotation.java3
-rw-r--r--src/main/java/org/torproject/metrics/collector/conf/Configuration.java1
-rw-r--r--src/main/java/org/torproject/metrics/collector/conf/Key.java8
-rw-r--r--src/main/java/org/torproject/metrics/collector/persist/SnowflakeStatsPersistence.java37
-rw-r--r--src/main/java/org/torproject/metrics/collector/snowflake/SnowflakeStatsDownloader.java153
-rw-r--r--src/main/java/org/torproject/metrics/collector/sync/SyncPersistence.java5
-rw-r--r--src/main/resources/collector.properties20
-rwxr-xr-xsrc/main/resources/create-tarballs.sh5
-rw-r--r--src/main/resources/docs/PROTOCOL32
-rw-r--r--src/test/java/org/torproject/metrics/collector/conf/ConfigurationTest.java2
-rw-r--r--src/test/java/org/torproject/metrics/collector/cron/CollecTorMainTest.java1
-rw-r--r--src/test/java/org/torproject/metrics/collector/cron/SchedulerTest.java9
15 files changed, 275 insertions, 7 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 66e53ed..d43b932 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@
copied to the `lib/` directory manually. Current dependency
versions resolved by Ivy are the same as in Debian stretch with
few exceptions.
+ - Archive snowflake statistics.
# Changes in version 1.9.1 - 2019-05-29
diff --git a/build.xml b/build.xml
index 39180c7..c8527ea 100644
--- a/build.xml
+++ b/build.xml
@@ -12,7 +12,7 @@
<property name="release.version" value="1.9.1-dev" />
<property name="project-main-class" value="org.torproject.metrics.collector.Main" />
<property name="name" value="collector"/>
- <property name="metricslibversion" value="2.6.2" />
+ <property name="metricslibversion" value="2.6.2-dev" />
<property name="jarincludes" value="collector.properties logback.xml" />
<patternset id="runtime" >
diff --git a/src/main/java/org/torproject/metrics/collector/Main.java b/src/main/java/org/torproject/metrics/collector/Main.java
index 46e93af..6907e93 100644
--- a/src/main/java/org/torproject/metrics/collector/Main.java
+++ b/src/main/java/org/torproject/metrics/collector/Main.java
@@ -14,6 +14,7 @@ import org.torproject.metrics.collector.exitlists.ExitListDownloader;
import org.torproject.metrics.collector.indexer.CreateIndexJson;
import org.torproject.metrics.collector.onionperf.OnionPerfDownloader;
import org.torproject.metrics.collector.relaydescs.ArchiveWriter;
+import org.torproject.metrics.collector.snowflake.SnowflakeStatsDownloader;
import org.torproject.metrics.collector.webstats.SanitizeWeblogs;
import org.slf4j.Logger;
@@ -53,6 +54,8 @@ public class Main {
collecTorMains.put(Key.RelaydescsActivated, ArchiveWriter.class);
collecTorMains.put(Key.OnionPerfActivated, OnionPerfDownloader.class);
collecTorMains.put(Key.WebstatsActivated, SanitizeWeblogs.class);
+ collecTorMains.put(Key.SnowflakeStatsActivated,
+ SnowflakeStatsDownloader.class);
}
private static Configuration conf = new Configuration();
diff --git a/src/main/java/org/torproject/metrics/collector/conf/Annotation.java b/src/main/java/org/torproject/metrics/collector/conf/Annotation.java
index 2e47df0..8cd3324 100644
--- a/src/main/java/org/torproject/metrics/collector/conf/Annotation.java
+++ b/src/main/java/org/torproject/metrics/collector/conf/Annotation.java
@@ -18,7 +18,8 @@ public enum Annotation {
Server("@type server-descriptor 1.0\n"),
Status("@type bridge-network-status 1.2\n"),
OnionPerf("@type torperf 1.1\n"),
- Vote("@type network-status-vote-3 1.0\n");
+ Vote("@type network-status-vote-3 1.0\n"),
+ SnowflakeStats("@type snowflake-stats 1.0\n");
private final String annotation;
private final byte[] bytes;
diff --git a/src/main/java/org/torproject/metrics/collector/conf/Configuration.java b/src/main/java/org/torproject/metrics/collector/conf/Configuration.java
index 69d3bcd..27f5125 100644
--- a/src/main/java/org/torproject/metrics/collector/conf/Configuration.java
+++ b/src/main/java/org/torproject/metrics/collector/conf/Configuration.java
@@ -91,6 +91,7 @@ public class Configuration extends Observable implements Cloneable {
|| this.getBool(Key.ExitlistsActivated)
|| this.getBool(Key.UpdateindexActivated)
|| this.getBool(Key.OnionPerfActivated)
+ || this.getBool(Key.SnowflakeStatsActivated)
|| this.getBool(Key.WebstatsActivated))) {
throw new ConfigurationException("Nothing is activated!\n"
+ "Please edit collector.properties. Exiting.");
diff --git a/src/main/java/org/torproject/metrics/collector/conf/Key.java b/src/main/java/org/torproject/metrics/collector/conf/Key.java
index ba4bcd9..e683fe2 100644
--- a/src/main/java/org/torproject/metrics/collector/conf/Key.java
+++ b/src/main/java/org/torproject/metrics/collector/conf/Key.java
@@ -66,7 +66,13 @@ public enum Key {
WebstatsActivated(Boolean.class),
WebstatsLimits(Boolean.class),
WebstatsOffsetMinutes(Integer.class),
- WebstatsPeriodMinutes(Integer.class);
+ WebstatsPeriodMinutes(Integer.class),
+ SnowflakeStatsActivated(Boolean.class),
+ SnowflakeStatsOffsetMinutes(Integer.class),
+ SnowflakeStatsPeriodMinutes(Integer.class),
+ SnowflakeStatsUrl(URL.class),
+ SnowflakeStatsSources(SourceType[].class),
+ SnowflakeStatsSyncOrigins(URL[].class);
private Class clazz;
private static Set<String> keys;
diff --git a/src/main/java/org/torproject/metrics/collector/persist/SnowflakeStatsPersistence.java b/src/main/java/org/torproject/metrics/collector/persist/SnowflakeStatsPersistence.java
new file mode 100644
index 0000000..ee6e029
--- /dev/null
+++ b/src/main/java/org/torproject/metrics/collector/persist/SnowflakeStatsPersistence.java
@@ -0,0 +1,37 @@
+/* Copyright 2019 The Tor Project
+ * See LICENSE for licensing information */
+
+package org.torproject.metrics.collector.persist;
+
+import org.torproject.descriptor.SnowflakeStats;
+import org.torproject.metrics.collector.conf.Annotation;
+
+import java.nio.file.Paths;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+
+public class SnowflakeStatsPersistence
+ extends DescriptorPersistence<SnowflakeStats> {
+
+ private static final String SNOWFLAKES = "snowflakes";
+
+ public SnowflakeStatsPersistence(SnowflakeStats desc) {
+ super(desc, Annotation.SnowflakeStats.bytes());
+ calculatePaths();
+ }
+
+ private void calculatePaths() {
+ DateTimeFormatter directoriesFormatter = DateTimeFormatter
+ .ofPattern("uuuu/MM/dd").withZone(ZoneOffset.UTC);
+ String[] directories = this.desc.snowflakeStatsEnd()
+ .format(directoriesFormatter).split("/");
+ DateTimeFormatter fileFormatter = DateTimeFormatter
+ .ofPattern("uuuu-MM-dd-HH-mm-ss").withZone(ZoneOffset.UTC);
+ String fileOut = this.desc.snowflakeStatsEnd().format(fileFormatter)
+ + "-snowflake-stats";
+ this.recentPath = Paths.get(SNOWFLAKES, fileOut).toString();
+ this.storagePath = Paths.get(SNOWFLAKES, directories[0], directories[1],
+ directories[2], fileOut).toString();
+ }
+}
+
diff --git a/src/main/java/org/torproject/metrics/collector/snowflake/SnowflakeStatsDownloader.java b/src/main/java/org/torproject/metrics/collector/snowflake/SnowflakeStatsDownloader.java
new file mode 100644
index 0000000..74e7849
--- /dev/null
+++ b/src/main/java/org/torproject/metrics/collector/snowflake/SnowflakeStatsDownloader.java
@@ -0,0 +1,153 @@
+/* Copyright 2019 The Tor Project
+ * See LICENSE for licensing information */
+
+package org.torproject.metrics.collector.snowflake;
+
+import org.torproject.descriptor.Descriptor;
+import org.torproject.descriptor.DescriptorParser;
+import org.torproject.descriptor.DescriptorSourceFactory;
+import org.torproject.descriptor.SnowflakeStats;
+import org.torproject.metrics.collector.conf.Annotation;
+import org.torproject.metrics.collector.conf.Configuration;
+import org.torproject.metrics.collector.conf.ConfigurationException;
+import org.torproject.metrics.collector.conf.Key;
+import org.torproject.metrics.collector.cron.CollecTorMain;
+import org.torproject.metrics.collector.persist.SnowflakeStatsPersistence;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.SortedSet;
+import java.util.Stack;
+import java.util.TreeSet;
+
+public class SnowflakeStatsDownloader extends CollecTorMain {
+
+ private static final Logger logger = LoggerFactory.getLogger(
+ SnowflakeStatsDownloader.class);
+
+ private String recentPathName;
+
+ /** Instantiate the snowflake-stats module using the given configuration. */
+ public SnowflakeStatsDownloader(Configuration config) {
+ super(config);
+ this.mapPathDescriptors.put("recent/snowflakes", SnowflakeStats.class);
+ }
+
+ @Override
+ public String module() {
+ return "SnowflakeStats";
+ }
+
+ @Override
+ protected String syncMarker() {
+ return "SnowflakeStats";
+ }
+
+ @Override
+ protected void startProcessing() throws ConfigurationException {
+
+ this.recentPathName = config.getPath(Key.RecentPath).toString();
+ logger.debug("Downloading snowflake stats...");
+ ByteArrayOutputStream downloadedSnowflakeStats
+ = new ByteArrayOutputStream();
+ URL url = config.getUrl(Key.SnowflakeStatsUrl);
+ try {
+ HttpURLConnection huc = (HttpURLConnection) url.openConnection();
+ huc.setRequestMethod("GET");
+ huc.setReadTimeout(5000);
+ huc.connect();
+ int response = huc.getResponseCode();
+ if (response != 200) {
+ logger.warn("Could not download snowflake stats. Response code {}",
+ response);
+ return;
+ }
+ try (BufferedInputStream in = new BufferedInputStream(
+ huc.getInputStream())) {
+ int len;
+ byte[] data = new byte[1024];
+ while ((len = in.read(data, 0, 1024)) >= 0) {
+ downloadedSnowflakeStats.write(data, 0, len);
+ }
+ }
+ logger.debug("Finished downloading snowflake stats.");
+ } catch (IOException e) {
+ logger.warn("Failed downloading snowflake stats", e);
+ return;
+ }
+
+ DescriptorParser descriptorParser =
+ DescriptorSourceFactory.createDescriptorParser();
+ SortedSet<LocalDateTime> snowflakeStatsEnds = new TreeSet<>();
+ String outputPathName = config.getPath(Key.OutputPath).toString();
+ for (Descriptor descriptor : descriptorParser.parseDescriptors(
+ downloadedSnowflakeStats.toByteArray(), null, null)) {
+ if (descriptor instanceof SnowflakeStats) {
+ SnowflakeStats snowflakeStats = (SnowflakeStats) descriptor;
+ LocalDateTime snowflakeStatsEnd = snowflakeStats.snowflakeStatsEnd();
+ snowflakeStatsEnds.add(snowflakeStatsEnd);
+ SnowflakeStatsPersistence persistence
+ = new SnowflakeStatsPersistence(snowflakeStats);
+ File tarballFile = new File(outputPathName + "/"
+ + persistence.getStoragePath());
+ if (tarballFile.exists()) {
+ continue;
+ }
+ File rsyncFile = new File(this.recentPathName + "/"
+ + persistence.getRecentPath());
+ File[] outputFiles = new File[] { tarballFile, rsyncFile };
+ for (File outputFile : outputFiles) {
+ try {
+ outputFile.getParentFile().mkdirs();
+ OutputStream os = new FileOutputStream(outputFile);
+ os.write(Annotation.SnowflakeStats.bytes());
+ os.write(snowflakeStats.getRawDescriptorBytes());
+ os.close();
+ } catch (IOException e) {
+ logger.warn("Could not write downloaded snowflake stats to {}",
+ outputFile.getAbsolutePath(), e);
+ }
+ }
+ }
+ }
+ if (snowflakeStatsEnds.isEmpty()) {
+ logger.warn("Could not parse downloaded snowflake stats.");
+ return;
+ } else if (snowflakeStatsEnds.last().isBefore(LocalDateTime.now()
+ .minusHours(48L))) {
+ logger.warn("The latest snowflake stats are older than 48 hours: {}.",
+ snowflakeStatsEnds.last());
+ }
+
+ this.cleanUpRsyncDirectory();
+ }
+
+ /** Delete all files from the rsync directory that have not been modified
+ * in the last three days. */
+ public void cleanUpRsyncDirectory() {
+ long cutOffMillis = System.currentTimeMillis()
+ - 3L * 24L * 60L * 60L * 1000L;
+ Stack<File> allFiles = new Stack<>();
+ allFiles.add(new File(recentPathName));
+ while (!allFiles.isEmpty()) {
+ File file = allFiles.pop();
+ if (file.isDirectory()) {
+ allFiles.addAll(Arrays.asList(file.listFiles()));
+ } else if (file.lastModified() < cutOffMillis) {
+ file.delete();
+ }
+ }
+ }
+}
+
diff --git a/src/main/java/org/torproject/metrics/collector/sync/SyncPersistence.java b/src/main/java/org/torproject/metrics/collector/sync/SyncPersistence.java
index 0d344bf..4b3b7bc 100644
--- a/src/main/java/org/torproject/metrics/collector/sync/SyncPersistence.java
+++ b/src/main/java/org/torproject/metrics/collector/sync/SyncPersistence.java
@@ -13,6 +13,7 @@ import org.torproject.descriptor.RelayExtraInfoDescriptor;
import org.torproject.descriptor.RelayNetworkStatusConsensus;
import org.torproject.descriptor.RelayNetworkStatusVote;
import org.torproject.descriptor.RelayServerDescriptor;
+import org.torproject.descriptor.SnowflakeStats;
import org.torproject.descriptor.TorperfResult;
import org.torproject.descriptor.WebServerAccessLog;
import org.torproject.metrics.collector.conf.Configuration;
@@ -29,6 +30,7 @@ import org.torproject.metrics.collector.persist.MicroConsensusPersistence;
import org.torproject.metrics.collector.persist.OnionPerfPersistence;
import org.torproject.metrics.collector.persist.PersistenceUtils;
import org.torproject.metrics.collector.persist.ServerDescriptorPersistence;
+import org.torproject.metrics.collector.persist.SnowflakeStatsPersistence;
import org.torproject.metrics.collector.persist.StatusPersistence;
import org.torproject.metrics.collector.persist.VotePersistence;
import org.torproject.metrics.collector.persist.WebServerAccessLogPersistence;
@@ -143,6 +145,9 @@ public class SyncPersistence {
case "BandwidthFile":
descPersist = new BandwidthFilePersistence((BandwidthFile) desc);
break;
+ case "SnowflakeStats":
+ descPersist = new SnowflakeStatsPersistence((SnowflakeStats) desc);
+ break;
default:
log.trace("Invalid descriptor type {} for sync-merge.",
clazz.getName());
diff --git a/src/main/resources/collector.properties b/src/main/resources/collector.properties
index 292e876..df79946 100644
--- a/src/main/resources/collector.properties
+++ b/src/main/resources/collector.properties
@@ -47,6 +47,13 @@ WebstatsActivated = false
WebstatsPeriodMinutes = 360
# offset in minutes since the epoch and
WebstatsOffsetMinutes = 31
+# the following defines, if this module is activated
+SnowflakeStatsActivated = false
+# period in minutes
+SnowflakeStatsPeriodMinutes = 480
+# offset in minutes since the epoch and
+SnowflakeStatsOffsetMinutes = 100
+
##########################################
## All below can be changed at runtime.
#####
@@ -178,3 +185,16 @@ WebstatsLocalOrigins = in/webstats
# Default 'true' behaves as stated in section 4 of
# https://metrics.torproject.org/web-server-logs.html
WebstatsLimits = true
+#
+#
+######## Snowflake statistics ########
+#
+## Define descriptor sources
+# possible values: Sync, Remote
+SnowflakeStatsSources = Remote
+## Retrieve files from the following instances.
+## List of URLs separated by comma.
+SnowflakeStatsSyncOrigins = https://collector.torproject.org
+## Where to download snowflake statistics from.
+SnowflakeStatsUrl = snowflake-broker@bamsoftware.com/metrics
+#
diff --git a/src/main/resources/create-tarballs.sh b/src/main/resources/create-tarballs.sh
index 7e4668a..2ba003d 100755
--- a/src/main/resources/create-tarballs.sh
+++ b/src/main/resources/create-tarballs.sh
@@ -59,6 +59,7 @@ TARBALLS=(
bridge-server-descriptors-$YEARTWO-$MONTHTWO
bridge-extra-infos-$YEARONE-$MONTHONE
bridge-extra-infos-$YEARTWO-$MONTHTWO
+ snowflakes
)
TARBALLS=($(printf "%s\n" "${TARBALLS[@]}" | uniq))
@@ -86,6 +87,7 @@ DIRECTORIES=(
$OUTDIR/bridge-descriptors/$YEARTWO/$MONTHTWO/server-descriptors/
$OUTDIR/bridge-descriptors/$YEARONE/$MONTHONE/extra-infos/
$OUTDIR/bridge-descriptors/$YEARTWO/$MONTHTWO/extra-infos/
+ $OUTDIR/snowflakes/
)
DIRECTORIES=($(printf "%s\n" "${DIRECTORIES[@]}" | uniq))
@@ -169,4 +171,7 @@ ln -f -s -t $ARCHIVEDIR/torperf/ $TARBALLTARGETDIR/torperf-20??-??.tar.xz
mkdir -p $ARCHIVEDIR/webstats/
ln -f -s -t $ARCHIVEDIR/webstats/ $TARBALLTARGETDIR/webstats-20??-??.tar
+mkdir -p $ARCHIVEDIR/snowflakes/
+ln -f -s -t $ARCHIVEDIR/snowflakes/ $TARBALLTARGETDIR/snowflakes.tar.xz
+
echo `date` "Finished."
diff --git a/src/main/resources/docs/PROTOCOL b/src/main/resources/docs/PROTOCOL
index 58ed4dc..4560026 100644
--- a/src/main/resources/docs/PROTOCOL
+++ b/src/main/resources/docs/PROTOCOL
@@ -45,6 +45,7 @@
* exit-lists
* relay-descriptors
* torperf
+ * snowflakes
The substructure of these folders differs depending on their content.
@@ -116,6 +117,12 @@
* for bandwidths, from the file_created value if available, otherwise the
timestamp.
+2.5 'snowflakes' below 'archive'
+
+ 'snowflakes' contains a single compressed tarball with snowflake statistics:
+
+ * snowflakes.tar.xz
+
3.0 Index Files
The index.json file and its compressed versions of various types are
@@ -132,6 +139,7 @@
* exit-lists
* relay-descriptors
* torperf
+ * snowflakes
4.1 'exit-lists' and 'torperf' below 'recent'
@@ -254,6 +262,16 @@
'webstats' contains compressed log files named according to
the 'Tor web server logs' specification, section 4.3 [0].
+4.5 'snowflakes' below 'recent'
+
+ 'snowflakes' contains files named
+
+ year DASH month DASH day DASH hour DASH minute DASH second
+ DASH SNOWFLAKESTATS
+
+ Where SNOWFLAKESTATS is the string "snowflake-stats" and all time related
+ values are derived from the snowflake statistics interval end.
+
5.0 The Tar-ball's Directory Structure and the Internal Structure
The 'out' directory is the internal storage that is used for
@@ -266,8 +284,9 @@
* exit-lists
* relay-descriptors
* torperf
+ * snowflakes
- (There has been a fifth subdirectory 'bridge-pool-assignments' which has been
+ (There has been another subdirectory 'bridge-pool-assignments' which has been
removed when CollecTor stopped collecting those descriptors. However, it's
structure can still be found in the tarballs.)
@@ -416,6 +435,17 @@
'webstats' contains compressed log files structured and named according
to the 'Tor web server logs' specification, section 4.3 [0].
+5.5 'snowflakes' below 'out'
+
+ 'snowflakes' contains the subdirectory structure
+
+ year SEP month SEP day
+
+ Where the time related values are taken from the snowflake statistics
+ interval end.
+
+ The files are named according to the structure in 4.5.
+
6.0 The 'contrib' Folder
The 'contrib' folder contains third-party contributions.
diff --git a/src/test/java/org/torproject/metrics/collector/conf/ConfigurationTest.java b/src/test/java/org/torproject/metrics/collector/conf/ConfigurationTest.java
index 4ac623e..3a69c0c 100644
--- a/src/test/java/org/torproject/metrics/collector/conf/ConfigurationTest.java
+++ b/src/test/java/org/torproject/metrics/collector/conf/ConfigurationTest.java
@@ -38,7 +38,7 @@ public class ConfigurationTest {
public void testKeyCount() {
assertEquals("The number of properties keys in enum Key changed."
+ "\n This test class should be adapted.",
- 53, Key.values().length);
+ 59, Key.values().length);
}
@Test()
diff --git a/src/test/java/org/torproject/metrics/collector/cron/CollecTorMainTest.java b/src/test/java/org/torproject/metrics/collector/cron/CollecTorMainTest.java
index 78b6ac7..d0fe173 100644
--- a/src/test/java/org/torproject/metrics/collector/cron/CollecTorMainTest.java
+++ b/src/test/java/org/torproject/metrics/collector/cron/CollecTorMainTest.java
@@ -72,6 +72,7 @@ public class CollecTorMainTest {
case "Exitlist":
case "OnionPerf":
case "Webstats":
+ case "SnowflakeStats":
assertNotNull("Property '" + key
+ "' not specified in " + Main.CONF_FILE + ".",
props.getProperty(key));
diff --git a/src/test/java/org/torproject/metrics/collector/cron/SchedulerTest.java b/src/test/java/org/torproject/metrics/collector/cron/SchedulerTest.java
index e0496fb..3f20646 100644
--- a/src/test/java/org/torproject/metrics/collector/cron/SchedulerTest.java
+++ b/src/test/java/org/torproject/metrics/collector/cron/SchedulerTest.java
@@ -31,7 +31,9 @@ public class SchedulerTest {
+ "UpdateindexActivated=true\nUpdateindexPeriodMinutes=1\n"
+ "UpdateindexOffsetMinutes=0\n"
+ "BridgedescsActivated=true\nBridgedescsPeriodMinutes=1\n"
- + "BridgedescsOffsetMinutes=0\n";
+ + "BridgedescsOffsetMinutes=0\n"
+ + "SnowflakeStatsActivated=true\nSnowflakeStatsPeriodMinutes=1\n"
+ + "SnowflakeStatsOffsetMinutes=0\n";
@Test()
public void testSimpleSchedule() throws Exception {
@@ -42,6 +44,7 @@ public class SchedulerTest {
ctms.put(Key.BridgedescsActivated, Dummy.class);
ctms.put(Key.RelaydescsActivated, Dummy.class);
ctms.put(Key.ExitlistsActivated, Dummy.class);
+ ctms.put(Key.SnowflakeStatsActivated, Dummy.class);
ctms.put(Key.UpdateindexActivated, Dummy.class);
Field schedulerField = Scheduler.class.getDeclaredField("scheduler");
schedulerField.setAccessible(true);
@@ -74,6 +77,7 @@ public class SchedulerTest {
ctms.put(Key.BridgedescsActivated, Counter.class);
ctms.put(Key.RelaydescsActivated, Counter.class);
ctms.put(Key.ExitlistsActivated, Counter.class);
+ ctms.put(Key.SnowflakeStatsActivated, Counter.class);
ctms.put(Key.UpdateindexActivated, Counter.class);
conf.setProperty(Key.BridgeSources.name(), "Local");
conf.setProperty(Key.RelaySources.name(), "Remote");
@@ -84,7 +88,7 @@ public class SchedulerTest {
schedulerField.get(Scheduler.getInstance());
Scheduler.getInstance().scheduleModuleRuns(ctms, conf);
Scheduler.getInstance().shutdownScheduler();
- assertEquals(5, Counter.count.get());
+ assertEquals(6, Counter.count.get());
}
@Ignore("This test takes 180 seconds, which is too long.")
@@ -97,6 +101,7 @@ public class SchedulerTest {
ctms.put(Key.BridgedescsActivated, Broken.class);
ctms.put(Key.RelaydescsActivated, Broken.class);
ctms.put(Key.ExitlistsActivated, Broken.class);
+ ctms.put(Key.SnowflakeStatsActivated, Broken.class);
ctms.put(Key.UpdateindexActivated, Broken.class);
Field schedulerField = Scheduler.class.getDeclaredField("scheduler");
schedulerField.setAccessible(true);