Skip to content

Commit 950ffcd

Browse files
authored
Merge pull request #89 from ie3-institute/ck/#88-fixUnitImplementation
Fix malicious implementation of units
2 parents 2842576 + 2d8dd2c commit 950ffcd

File tree

4 files changed

+54
-17
lines changed

4 files changed

+54
-17
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased/Snapshot]
88

9+
## [1.5.1]
10+
### Fixed
11+
- Malicious implementation of some units + additional tests for transformed units
12+
913
## [1.5]
1014

1115
### Added
@@ -57,7 +61,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5761
### Fixed
5862
- fixes + extensions in StandardUnits
5963

60-
[Unreleased/Snapshot]: https://github.com/ie3-institute/powersystemutils/compare/v1.5...HEAD
64+
[Unreleased/Snapshot]: https://github.com/ie3-institute/powersystemutils/compare/v1.5.1...HEAD
65+
[1.5.1]: https://github.com/ie3-institute/powersystemutils/compare/v1.4...v1.5.1
6166
[1.5]: https://github.com/ie3-institute/powersystemutils/compare/v1.4...v1.5
6267
[1.4]: https://github.com/ie3-institute/powersystemutils/compare/v1.3.2...v1.4
6368
[1.3.2]: https://github.com/ie3-institute/powersystemutils/compare/v1.3.1...v1.3.2

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ ext {
2020
}
2121

2222
group = 'com.github.ie3-institute'
23-
version = '1.6-SNAPSHOT'
23+
version = '1.5.1'
2424
description = 'PowerSystemUtils'
2525
sourceCompatibility = javaVersion
2626
targetCompatibility = javaVersion

src/main/java/edu/ie3/util/quantities/PowerSystemUnits.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,19 @@ public class PowerSystemUnits extends Units {
4646

4747
/** Euro / km */
4848
public static final Unit<PricePerLength> EURO_PER_KILOMETRE =
49-
new ProductUnit<>(EURO.divide(MetricPrefix.KILO(METRE)));
49+
new ProductUnit<>(EURO.divide(KILOMETRE));
5050

5151
/** Euro / Wh */
5252
public static final Unit<EnergyPrice> EURO_PER_WATTHOUR =
53-
new ProductUnit<>(EURO.divide(Units.WATT.multiply(Units.HOUR)));
53+
new ProductUnit<>(EURO.divide(WATT.multiply(HOUR)));
5454

5555
/** Euro / kWh */
5656
public static final Unit<EnergyPrice> EURO_PER_KILOWATTHOUR =
57-
MetricPrefix.MILLI(EURO_PER_WATTHOUR);
57+
new TransformedUnit<>("€/kWh", EURO_PER_WATTHOUR, MultiplyConverter.of(1E-3));
5858

5959
/** Euro / MWh */
6060
public static final Unit<EnergyPrice> EURO_PER_MEGAWATTHOUR =
61-
MetricPrefix.MICRO(EURO_PER_WATTHOUR);
61+
new TransformedUnit<>("€/MWh", EURO_PER_WATTHOUR, MultiplyConverter.of(1E-6));
6262

6363
/** Degree */
6464
public static final Unit<Angle> DEGREE_GEOM =
@@ -83,11 +83,12 @@ public class PowerSystemUnits extends Units {
8383
public static final Unit<Energy> KILOVARHOUR = MetricPrefix.KILO(VARHOUR);
8484

8585
/** Watthour per metre */
86-
public static final Unit<SpecificEnergy> WATTHOUR_PER_METRE = new BaseUnit<>("Wh/m");
86+
public static final Unit<SpecificEnergy> WATTHOUR_PER_METRE =
87+
new ProductUnit<>(WATTHOUR.divide(METRE));
8788

8889
/** Kilowatthour per Kilometre */
8990
public static final Unit<SpecificEnergy> KILOWATTHOUR_PER_KILOMETRE =
90-
new AlternateUnit<>(WATTHOUR_PER_METRE, "kWh/km");
91+
new TransformedUnit<>("kWh/km", WATTHOUR_PER_METRE, MultiplyConverter.of(1d));
9192

9293
/** Watthour per squaremetre */
9394
public static final Unit<Irradiation> WATTHOUR_PER_SQUAREMETRE =
@@ -159,7 +160,8 @@ public class PowerSystemUnits extends Units {
159160
new ProductUnit<>(MetricPrefix.MICRO(SIEMENS).divide(KILOMETRE));
160161

161162
/** Farad per metre */
162-
public static final Unit<SpecificCapacitance> FARAD_PER_METRE = new BaseUnit<>("F/m");
163+
public static final Unit<SpecificCapacitance> FARAD_PER_METRE =
164+
new ProductUnit<>(FARAD.divide(METRE));
163165

164166
/** F / km */
165167
public static final Unit<SpecificCapacitance> FARAD_PER_KILOMETRE =
@@ -181,9 +183,10 @@ public class PowerSystemUnits extends Units {
181183
/* ==== Thermal Conductance ==== */
182184

183185
/** kW/K */
184-
public static final Unit<ThermalConductance> KILOWATT_PER_KELVIN = new BaseUnit<>("kW/K");
186+
public static final Unit<ThermalConductance> KILOWATT_PER_KELVIN =
187+
new ProductUnit<>(KILOWATT.divide(KELVIN));
185188

186-
private static final HashSet<String> registeredLabels = new HashSet<>();
189+
private static final HashSet<String> REGISTERED_LABELS = new HashSet<>();
187190

188191
static {
189192
addUnit(WATTHOUR, "Wh");
@@ -221,12 +224,13 @@ public class PowerSystemUnits extends Units {
221224
* return-value is null, the unit was already registered
222225
*/
223226
private static Unit<?> addUnit(Unit<?> unit, String label) {
224-
if (registeredLabels.contains(label)) {
227+
if (REGISTERED_LABELS.contains(label)) {
225228
logger.log(Level.FINE, "Label {} is already registered. Ignoring", label);
226229
return null;
227230
}
228231

229232
SimpleUnitFormat.getInstance().label(unit, label);
233+
REGISTERED_LABELS.add(label);
230234
return unit;
231235
}
232236
}

src/test/groovy/edu/ie3/util/quantities/PowerSystemUnitsTest.groovy

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,45 @@
55
*/
66
package edu.ie3.util.quantities
77

8+
import spock.lang.Shared
89
import spock.lang.Specification
910
import tech.units.indriya.quantity.Quantities
10-
import tech.units.indriya.unit.Units
11+
12+
import static edu.ie3.util.quantities.PowerSystemUnits.*
13+
import static tech.units.indriya.unit.Units.JOULE
14+
import static tech.units.indriya.unit.Units.RADIAN
1115

1216
class PowerSystemUnitsTest extends Specification {
17+
@Shared
18+
double testingTolerance = 1E-9
19+
20+
def "Transformed units are transferred correctly to their base units"() {
21+
when:
22+
def actualQuantity = quantity.to(baseUnit)
23+
24+
then:
25+
QuantityUtil.equals(expectedQuantity, actualQuantity, testingTolerance)
26+
27+
where:
28+
quantity | baseUnit || expectedQuantity
29+
Quantities.getQuantity(1d, EURO_PER_KILOWATTHOUR) | EURO_PER_WATTHOUR || Quantities.getQuantity(1E-3, EURO_PER_WATTHOUR)
30+
Quantities.getQuantity(1d, EURO_PER_MEGAWATTHOUR) | EURO_PER_WATTHOUR || Quantities.getQuantity(1E-6, EURO_PER_WATTHOUR)
31+
Quantities.getQuantity(1d, DEGREE_GEOM) | RADIAN || Quantities.getQuantity(0.017453292, RADIAN)
32+
Quantities.getQuantity(1d, WATTHOUR) | JOULE || Quantities.getQuantity(3600d, JOULE)
33+
Quantities.getQuantity(1d, VARHOUR) | JOULE || Quantities.getQuantity(3600d, JOULE)
34+
Quantities.getQuantity(1d, KILOWATTHOUR_PER_KILOMETRE) | WATTHOUR_PER_METRE || Quantities.getQuantity(1d, WATTHOUR_PER_METRE)
35+
Quantities.getQuantity(1d, PU_PER_HOUR) | PERCENT_PER_HOUR || Quantities.getQuantity(100d, PERCENT_PER_HOUR)
36+
Quantities.getQuantity(1d, FARAD_PER_KILOMETRE) | FARAD_PER_METRE || Quantities.getQuantity(1E-3, FARAD_PER_METRE)
37+
Quantities.getQuantity(1d, MICROFARAD_PER_KILOMETRE) | FARAD_PER_KILOMETRE || Quantities.getQuantity(1E-6, FARAD_PER_KILOMETRE)
38+
Quantities.getQuantity(1d, MICROFARAD_PER_KILOMETRE) | FARAD_PER_METRE || Quantities.getQuantity(1E-9, FARAD_PER_METRE)
39+
}
40+
1341
def "Angle quantities are transferred from degrees to radians correctly"() {
1442
given:
15-
def degreeQuantity = Quantities.getQuantity(degree, PowerSystemUnits.DEGREE_GEOM)
43+
def degreeQuantity = Quantities.getQuantity(degree, DEGREE_GEOM)
1644

1745
when:
18-
def actualValue = degreeQuantity.to(Units.RADIAN).value.doubleValue()
46+
def actualValue = degreeQuantity.to(RADIAN).value.doubleValue()
1947

2048
then:
2149
Math.abs(actualValue - radians) < 1E-12
@@ -30,10 +58,10 @@ class PowerSystemUnitsTest extends Specification {
3058

3159
def "Angle quantities are transferred from radians to radians degree"() {
3260
given:
33-
def radianQuantity = Quantities.getQuantity(radians, Units.RADIAN)
61+
def radianQuantity = Quantities.getQuantity(radians, RADIAN)
3462

3563
when:
36-
def actualValue = radianQuantity.to(PowerSystemUnits.DEGREE_GEOM).value.doubleValue()
64+
def actualValue = radianQuantity.to(DEGREE_GEOM).value.doubleValue()
3765

3866
then:
3967
Math.abs(actualValue - degree) < 1E-12

0 commit comments

Comments
 (0)