Skip to content

Commit

Permalink
Merge branch 'main' into queries-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
umbernhard authored Jun 24, 2024
2 parents c67978c + a5f140a commit da123e3
Show file tree
Hide file tree
Showing 20 changed files with 2,334 additions and 3,365 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ jobs:

- name: Classic Tests
run: cd server/eclipse-project; mvn -Dtest='us.freeandfair.corla.**' test

- name: IRV Tests
run: cd server/eclipse-project; mvn -Dtest='au.org.democracydevelopers.corla.**' test

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,15 @@ else if(loser_index != -1 && (winner_index == -1 || loser_index < winner_index))
prefix, score, id(), contestName, info.choices()));
return score;
}


/**
* {@inheritDoc}
*/
public String getDescription(){
return String.format("%s NEB %s: oneOver = %d; two Over = %d; oneUnder = %d, twoUnder = %d; " +
"other = %d; optimistic = %d; estimated = %d; risk %f.", winner, loser, oneVoteOverCount,
twoVoteOverCount, oneVoteUnderCount, twoVoteUnderCount, otherCount, optimisticSamplesToAudit,
estimatedSamplesToAudit, currentRisk);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
package au.org.democracydevelopers.corla.model.assertion;

import java.util.List;
import java.util.stream.Collectors;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import org.apache.log4j.LogManager;
Expand Down Expand Up @@ -82,4 +81,14 @@ else if (choices_left.get(0).equals(loser)) {
return score;
}

/**
* {@inheritDoc}
*/
public String getDescription(){
return String.format("%s NEN %s assuming (%s) are continuing: oneOver = %d; two Over = %d; " +
"oneUnder = %d, twoUnder = %d; other = %d; optimistic = %d; estimated = %d; risk %f.",
winner, loser, assumedContinuing, oneVoteOverCount, twoVoteOverCount, oneVoteUnderCount,
twoVoteUnderCount, otherCount, optimisticSamplesToAudit, estimatedSamplesToAudit, currentRisk);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
Democracy Developers IRV extensions to colorado-rla.
@copyright 2024 Colorado Department of State
These IRV extensions are designed to connect to a running instance of the raire
service (https://github.com/DemocracyDevelopers/raire-service), in order to
generate assertions that can be audited using colorado-rla.
The colorado-rla IRV extensions are free software: you can redistribute it and/or modify it under the terms
of the GNU Affero General Public License as published by the Free Software Foundation, either
version 3 of the License, or (at your option) any later version.
The colorado-rla IRV extensions are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with
raire-service. If not, see <https://www.gnu.org/licenses/>.
*/

package au.org.democracydevelopers.corla.query;

import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import org.hibernate.Session;
import au.org.democracydevelopers.corla.model.assertion.Assertion;
import us.freeandfair.corla.persistence.Persistence;

import javax.persistence.TypedQuery;

/**
* This class contains database queries relating to the retrieval of Assertions from the
* database. It contains a method that executes a query to retrieval all Assertions belonging
* to a specific contest, identified by name.
*/
public class AssertionQueries {

/**
* Class-wide logger.
*/
public static final Logger LOGGER = LogManager.getLogger(AssertionQueries.class);

/**
* Retrieve all assertions in the database belonging to the contest with the given name.
*
* @param contestName The contest name.
* @return the list of assertions defined for the contest.
* @throws RuntimeException when an unexpected error arose in assertion retrieval (not including
* a NoResultException, which is handled by returning an empty list).
*/
public static List<Assertion> matching(final String contestName) throws RuntimeException {
final String prefix = "[matching]";
try {
LOGGER.debug(String.format("%s Select query on assertion table, retrieving all " +
"assertions for contest with name %s.", prefix, contestName));

final Session s = Persistence.currentSession();
final TypedQuery<Assertion> q = s.createQuery("select ca from Assertion ca "
+ " where ca.contestName = :contestName", Assertion.class);
q.setParameter("contestName", contestName);

List<Assertion> result = q.getResultList();
LOGGER.debug(String.format("%s %d assertions retrieved for contest %s.", prefix,
result.size(), contestName));
return result;

} catch (javax.persistence.NoResultException e) {
final String msg = String.format("%s No assertions retrieved for contest %s.", prefix,
contestName);
LOGGER.warn(msg);
return new ArrayList<>();
}
catch(Exception e){
final String msg = String.format("%s An error arose when attempting to retrieve assertions " +
"for contest %s: %s", prefix, contestName, e.getMessage());
LOGGER.error(msg);
throw new RuntimeException(msg);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.EnumType;
Expand All @@ -38,6 +40,8 @@
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
Expand All @@ -63,7 +67,9 @@
@Entity
@Cacheable(true)
@Table(name = "comparison_audit")

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "audit_type")
@DiscriminatorValue("PLURALITY")
@SuppressWarnings({"PMD.ImmutableField", "PMD.ExcessiveClassLength",
"PMD.CyclomaticComplexity", "PMD.GodClass", "PMD.ModifiedCyclomaticComplexity",
"PMD.StdCyclomaticComplexity", "PMD.TooManyFields", "PMD.TooManyMethods",
Expand Down Expand Up @@ -129,11 +135,12 @@ public class ComparisonAudit implements PersistentEntity {
private BigDecimal my_gamma = Audit.GAMMA;

/**
* The diluted margin
* The diluted margin. [Democracy Developers: this must be accessible and modifiable by
* child classes of ComparisonAudit, hence we have made this attribute protected.]
*/
@Column(updatable = false, nullable = false,
precision = PRECISION, scale = SCALE)
private BigDecimal diluted_margin = BigDecimal.ONE;
protected BigDecimal diluted_margin = BigDecimal.ONE;

/**
* The risk limit.
Expand All @@ -150,16 +157,20 @@ public class ComparisonAudit implements PersistentEntity {

/**
* The number of samples to audit overall assuming no further overstatements.
* [Democracy Developers: this must be accessible and modifiable by child classes of
* ComparisonAudit, hence we have made this attribute protected.]
*/
@Column(nullable = false)
private Integer my_optimistic_samples_to_audit = 0;
protected Integer my_optimistic_samples_to_audit = 0;

/**
* The expected number of samples to audit overall assuming overstatements
* continue at the current rate.
* [Democracy Developers: this must be accessible and modifiable by child classes of
* ComparisonAudit, hence we have made this attribute protected.]
*/
@Column(nullable = false)
private Integer my_estimated_samples_to_audit = 0;
protected Integer my_estimated_samples_to_audit = 0;

/**
* The number of two-vote understatements recorded so far.
Expand Down Expand Up @@ -207,16 +218,20 @@ public class ComparisonAudit implements PersistentEntity {
/**
* A flag that indicates whether the optimistic ballots to audit
* estimate needs to be recalculated.
* [Democracy Developers: this must be accessible and modifiable by child classes of
* ComparisonAudit, hence we have made this attribute protected.]
*/
@Column(nullable = false)
private Boolean my_optimistic_recalculate_needed = true;
protected Boolean my_optimistic_recalculate_needed = true;

/**
* A flag that indicates whether the non-optimistic ballots to
* audit estimate needs to be recalculated
* audit estimate needs to be recalculated.
* [Democracy Developers: this must be accessible and modifiable by child classes of
* ComparisonAudit, hence we have made this attribute protected.]
*/
@Column(nullable = false)
private Boolean my_estimated_recalculate_needed = true;
protected Boolean my_estimated_recalculate_needed = true;

/**
* The sequence of CastVoteRecord ids for this contest ordered by County id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ us.freeandfair.corla.model.UploadedFile
au.org.democracydevelopers.corla.model.assertion.Assertion
au.org.democracydevelopers.corla.model.assertion.NEBAssertion
au.org.democracydevelopers.corla.model.assertion.NENAssertion
au.org.democracydevelopers.corla.model.IRVComparisonAudit
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@
import au.org.democracydevelopers.corla.model.ContestType;
import au.org.democracydevelopers.corla.model.IRVComparisonAudit;
import au.org.democracydevelopers.corla.model.vote.IRVParsingException;
import au.org.democracydevelopers.corla.util.TestClassWithDatabase;
import au.org.democracydevelopers.corla.util.testUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.ext.ScriptUtils;
import org.testcontainers.jdbc.JdbcDatabaseDelegate;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
Expand All @@ -37,6 +40,7 @@
import us.freeandfair.corla.model.*;
import us.freeandfair.corla.persistence.Persistence;

import javax.transaction.Transactional;
import java.io.IOException;
import java.io.Reader;
import java.math.BigDecimal;
Expand All @@ -61,7 +65,8 @@
* - an all-plurality contest is made into a (plain, plurality) ComparisonAudit,
* - a mixed-type contest, or a contest that is neither plurality nor IRV, throws an error.
*/
public class ComparisonAuditControllerTests {
@Transactional
public class ComparisonAuditControllerTests extends TestClassWithDatabase {

/**
* Class-wide logger
Expand All @@ -71,14 +76,7 @@ public class ComparisonAuditControllerTests {
/**
* Container for the mock-up database.
*/
static PostgreSQLContainer<?> postgres
= new PostgreSQLContainer<>("postgres:15-alpine")
// None of these actually have to be the same as the real database (except its name), but this
// makes it easy to match the setup scripts.
.withDatabaseName("corla")
.withUsername("corlaadmin")
.withPassword("corlasecret")
.withInitScript("SQL/corla-three-candidates-ten-votes-inconsistent-types.sql");
static PostgreSQLContainer<?> postgres = createTestContainer();

/**
* Blank properties for submitting to the DominionCVRExportParser instance.
Expand All @@ -103,14 +101,13 @@ public class ComparisonAuditControllerTests {
@BeforeClass
public static void beforeAll() {
postgres.start();
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.driver", "org.postgresql.Driver");
hibernateProperties.setProperty("hibernate.url", postgres.getJdbcUrl());
hibernateProperties.setProperty("hibernate.user", postgres.getUsername());
hibernateProperties.setProperty("hibernate.pass", postgres.getPassword());
hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQL9Dialect");
Persistence.setProperties(hibernateProperties);
Persistence.beginTransaction();
Persistence.setProperties(createHibernateProperties(postgres));

var containerDelegate = new JdbcDatabaseDelegate(postgres, "");
ScriptUtils.runInitScript(containerDelegate,
"SQL/co-counties.sql");
ScriptUtils.runInitScript(containerDelegate,
"SQL/corla-three-candidates-ten-votes-inconsistent-types.sql");

}

Expand Down
Loading

0 comments on commit da123e3

Please sign in to comment.