[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [collector/release] Archive snowflake statistics.
commit 569bb83ff5e50843079ebd1150801a8bd8efa747
Author: Karsten Loesing <karsten.loesing@xxxxxxx>
Date: Wed Aug 14 08:51:29 2019 +0200
Archive snowflake statistics.
Implements #29461.
---
CHANGELOG.md | 2 +
build.xml | 2 +-
.../org/torproject/metrics/collector/Main.java | 3 +
.../metrics/collector/conf/Annotation.java | 3 +-
.../metrics/collector/conf/Configuration.java | 1 +
.../org/torproject/metrics/collector/conf/Key.java | 8 +-
.../persist/SnowflakeStatsPersistence.java | 37 ++++
.../snowflake/SnowflakeStatsDownloader.java | 191 +++++++++++++++++++++
.../metrics/collector/sync/SyncPersistence.java | 5 +
src/main/resources/collector.properties | 20 +++
src/main/resources/create-tarballs.sh | 7 +
src/main/resources/docs/PROTOCOL | 33 +++-
.../metrics/collector/conf/ConfigurationTest.java | 2 +-
.../metrics/collector/cron/CollecTorMainTest.java | 1 +
.../metrics/collector/cron/SchedulerTest.java | 9 +-
15 files changed, 317 insertions(+), 7 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4fd0401..c537d22 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,8 @@
versions resolved by Ivy are the same as in Debian stretch with
few exceptions.
- Remove Cobertura from the build process.
+ - Archive snowflake statistics.
+ - Update to metrics-lib 2.7.0.
# Changes in version 1.9.1 - 2019-05-29
diff --git a/build.xml b/build.xml
index 39180c7..d1d5b70 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.7.0" />
<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..4f7994e
--- /dev/null
+++ b/src/main/java/org/torproject/metrics/collector/snowflake/SnowflakeStatsDownloader.java
@@ -0,0 +1,191 @@
+/* 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...");
+ URL url = config.getUrl(Key.SnowflakeStatsUrl);
+ ByteArrayOutputStream downloadedSnowflakeStats
+ = this.downloadFromHttpServer(url);
+ if (null == downloadedSnowflakeStats) {
+ return;
+ }
+ logger.debug("Finished downloading {}.", url);
+
+ 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) {
+ this.writeToFile(outputFile, Annotation.SnowflakeStats.bytes(),
+ snowflakeStats.getRawDescriptorBytes());
+ }
+ }
+ }
+ 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();
+ }
+
+ /**
+ * Download the given URL from an HTTP server and return a stream with
+ * downloaded bytes.
+ *
+ * <p>If anything goes wrong while downloading, log a warning and return
+ * {@code null}.</p>
+ *
+ * @param url URL to download.
+ * @return Stream with downloaded bytes, or {@code null} if an error has
+ * occurred.
+ */
+ private ByteArrayOutputStream downloadFromHttpServer(URL url) {
+ ByteArrayOutputStream downloadedBytes = new ByteArrayOutputStream();
+ 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 {}. Response code {}", url, response);
+ return null;
+ }
+ try (BufferedInputStream in = new BufferedInputStream(
+ huc.getInputStream())) {
+ int len;
+ byte[] data = new byte[1024];
+ while ((len = in.read(data, 0, 1024)) >= 0) {
+ downloadedBytes.write(data, 0, len);
+ }
+ }
+ } catch (IOException e) {
+ logger.warn("Failed downloading {}.", url, e);
+ return null;
+ }
+ return downloadedBytes;
+ }
+
+ /**
+ * Write the given byte array(s) to the given file.
+ *
+ * <p>If the file already exists, it is overwritten. If the parent directory
+ * (or any of its parent directories) does not exist, it is created. If
+ * anything goes wrong, log a warning and return.</p>
+ *
+ * @param outputFile File to write to.
+ * @param bytes One or more byte arrays.
+ */
+ private void writeToFile(File outputFile, byte[] ... bytes) {
+ try {
+ if (!outputFile.getParentFile().exists()
+ && !outputFile.getParentFile().mkdirs()) {
+ logger.warn("Could not create parent directories of {}.", outputFile);
+ return;
+ }
+ OutputStream os = new FileOutputStream(outputFile);
+ for (byte[] b : bytes) {
+ os.write(b);
+ }
+ os.close();
+ } catch (IOException e) {
+ logger.warn("Could not write downloaded snowflake stats to {}",
+ outputFile.getAbsolutePath(), e);
+ }
+ }
+
+ /** 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..a4eed7a 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 = https://snowflake-broker.torproject.net/metrics
+#
diff --git a/src/main/resources/create-tarballs.sh b/src/main/resources/create-tarballs.sh
index 7e4668a..50b7fdb 100755
--- a/src/main/resources/create-tarballs.sh
+++ b/src/main/resources/create-tarballs.sh
@@ -59,6 +59,8 @@ TARBALLS=(
bridge-server-descriptors-$YEARTWO-$MONTHTWO
bridge-extra-infos-$YEARONE-$MONTHONE
bridge-extra-infos-$YEARTWO-$MONTHTWO
+ snowflakes-$YEARONE-$MONTHONE
+ snowflakes-$YEARTWO-$MONTHTWO
)
TARBALLS=($(printf "%s\n" "${TARBALLS[@]}" | uniq))
@@ -86,6 +88,8 @@ DIRECTORIES=(
$OUTDIR/bridge-descriptors/$YEARTWO/$MONTHTWO/server-descriptors/
$OUTDIR/bridge-descriptors/$YEARONE/$MONTHONE/extra-infos/
$OUTDIR/bridge-descriptors/$YEARTWO/$MONTHTWO/extra-infos/
+ $OUTDIR/snowflakes/$YEARONE/$MONTHONE/
+ $OUTDIR/snowflakes/$YEARTWO/$MONTHTWO/
)
DIRECTORIES=($(printf "%s\n" "${DIRECTORIES[@]}" | uniq))
@@ -169,4 +173,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-20??-??.tar.xz
+
echo `date` "Finished."
diff --git a/src/main/resources/docs/PROTOCOL b/src/main/resources/docs/PROTOCOL
index 58ed4dc..478f168 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,13 @@
* for bandwidths, from the file_created value if available, otherwise the
timestamp.
+2.5 'snowflakes' below 'archive'
+
+ 'snowflakes' contains compressed tarballs with snowflake statistics,
+ named in the following way:
+
+ 'snowflakes' DASH year DASH month DOT TAR DOT compression-type
+
3.0 Index Files
The index.json file and its compressed versions of various types are
@@ -132,6 +140,7 @@
* exit-lists
* relay-descriptors
* torperf
+ * snowflakes
4.1 'exit-lists' and 'torperf' below 'recent'
@@ -254,6 +263,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 +285,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 +436,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);
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits