diff --git a/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/api/access/PermissionEmitter.java b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/api/access/PermissionEmitter.java index c9ffe08d4..3f5f4f064 100644 --- a/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/api/access/PermissionEmitter.java +++ b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/api/access/PermissionEmitter.java @@ -17,20 +17,26 @@ import org.eclipse.passage.lic.api.conditions.LicensingCondition; /** - * Interface of a service responsible for the third step of access cycle: condition evaluation. - * According to the contract, a service must be able to evaluate given {@link LicensingCondition}s against the current program runtime. - * As a result of evaluation, for a {@link LicensingCondition} a {@link FeaturePermission} must be emitted - * in the case all of the {@link LicensingCondition}'s terms are met at the current program runtime. + * Interface of a service responsible for the third step of access + * cycle: condition evaluation. According to the contract, a service must be + * able to evaluate given {@link LicensingCondition}s against the current + * program runtime. As a result of evaluation, for a {@link LicensingCondition} + * a {@link FeaturePermission} must be emitted in the case all of the + * {@link LicensingCondition}'s terms are met at the current program runtime. * * @see org.eclipse.passage.lic.api.conditions.ConditionMiner * @since 0.4.0 + * @deprecated use 1.0 PermissionEmittingService */ +@Deprecated public interface PermissionEmitter { /** - * Evaluates the collection of {@link LicensingCondition}s to emit a collection of {@link FeaturePermission}. + * Evaluates the collection of {@link LicensingCondition}s to emit a collection + * of {@link FeaturePermission}. * * @param configuration general configuration for the whole access cycle - * @param conditions source conditions to be evaluated against the current program runtime + * @param conditions source conditions to be evaluated against the current + * program runtime * @since 0.4.0 */ Iterable emitPermissions(LicensingConfiguration configuration, diff --git a/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/AccessCycleConfiguration.java b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/AccessCycleConfiguration.java index 45037e0fa..d5f070117 100644 --- a/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/AccessCycleConfiguration.java +++ b/bundles/org.eclipse.passage.lic.api/src/org/eclipse/passage/lic/internal/api/AccessCycleConfiguration.java @@ -12,12 +12,13 @@ *******************************************************************************/ package org.eclipse.passage.lic.internal.api; -import org.eclipse.passage.lic.internal.api.conditions.evaluation.PermissionEmittersRegistry; import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionEvaluatorsRegistry; import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionPasringRegistry; import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionTokenAssessorsRegistry; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.PermissionEmittersRegistry; import org.eclipse.passage.lic.internal.api.conditions.mining.ConditionTransportRegistry; import org.eclipse.passage.lic.internal.api.conditions.mining.MinedConditionsRegistry; +import org.eclipse.passage.lic.internal.api.inspection.RuntimeEnvironmentRegistry; import org.eclipse.passage.lic.internal.api.io.KeyKeeperRegistry; import org.eclipse.passage.lic.internal.api.io.StreamCodecRegistry; import org.eclipse.passage.lic.internal.api.requirements.ResolvedRequirementsRegistry; @@ -45,4 +46,6 @@ public interface AccessCycleConfiguration { ExpressionTokenAssessorsRegistry expressionAssessors(); + RuntimeEnvironmentRegistry environments(); + } diff --git a/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/OshiHardwareInspector.java b/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/OshiHardwareInspector.java index a6e1fd452..a89ece842 100644 --- a/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/OshiHardwareInspector.java +++ b/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/OshiHardwareInspector.java @@ -43,6 +43,11 @@ import oshi.software.os.OperatingSystem; import oshi.software.os.OperatingSystemVersion; +/** + * @deprecated use 1.0 internal State for the sake of scanning and + * HardawareEnvironemnt to get a corresponsing service + */ +@Deprecated @Component public class OshiHardwareInspector implements HardwareInspector { diff --git a/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/i18n/AssessmentMessages.properties b/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/i18n/AssessmentMessages.properties index 1c1f7f3b0..5b09dee93 100644 --- a/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/i18n/AssessmentMessages.properties +++ b/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/i18n/AssessmentMessages.properties @@ -1,3 +1,16 @@ +############################################################################### +# Copyright (c) 2020 ArSysOp and others +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Public License 2.0 which is available at +# https://www.eclipse.org/legal/epl-2.0/. +# +# SPDX-License-Identifier: EPL-2.0 +# +# Contributors: +# ArSysOp - initial API and implementation +############################################################################### + HardwareAssessmentService_error_on_assessment=Error property [%s] assessment for value [%s] -HardwareAssessmentService_no_hw_inspector=There is no runtive environment inpection service for type %s -State_error_reading_hw=Error reading hardware enviroment state +HardwareAssessmentService_no_hw_inspector=There is no runtime environment inspection service for type %s +State_error_reading_hw=Error reading hardware environment state diff --git a/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/tobemoved/GlanceOfState.java b/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/tobemoved/GlanceOfState.java index 68a6af19b..8256f9ab5 100644 --- a/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/tobemoved/GlanceOfState.java +++ b/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/tobemoved/GlanceOfState.java @@ -12,9 +12,16 @@ *******************************************************************************/ package org.eclipse.passage.lic.internal.oshi.tobemoved; +import java.util.List; import java.util.Objects; import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import org.eclipse.passage.lic.internal.api.inspection.EnvironmentProperty; +import org.eclipse.passage.lic.internal.base.inspection.hardware.Disk; + +@SuppressWarnings("restriction") final class GlanceOfState implements Supplier { private final State state; @@ -26,7 +33,37 @@ final class GlanceOfState implements Supplier { @Override public String get() { - return "ytbd"; //$NON-NLS-1$ + StringBuilder out = new StringBuilder(); + state.properties().stream() // + .collect(Collectors.groupingBy(EnvironmentProperty::family))// + .entrySet().stream() // + .forEach(e -> appendFamily(e.getKey(), e.getValue(), out)); + IntStream.range(0, state.disksAmount()) // + .forEach(no -> appendDisk(no, out)); + return out.toString(); + } + + private void appendDisk(int no, StringBuilder out) { + out.append(new Disk.Model().family())// + .append(" #")//$NON-NLS-1$ + .append(no)// + .append("\r\n"); //$NON-NLS-1$ + state.diskProperties(no).stream() // + .forEach(p -> appendProperty(p, state.diskValue(no, p), out)); + } + + private void appendFamily(String family, List properties, StringBuilder out) { + out.append(family).append("\r\n"); //$NON-NLS-1$ + properties.stream().forEach(p -> appendProperty(p, state.value(p), out)); + } + + private StringBuilder appendProperty(EnvironmentProperty property, String value, StringBuilder out) { + out.append("\t") //$NON-NLS-1$ + .append(property.name()) // + .append(": ") //$NON-NLS-1$ + .append(value)// + .append("\r\n"); //$NON-NLS-1$ + return out; } } diff --git a/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/tobemoved/HardwareEnvironment.java b/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/tobemoved/HardwareEnvironment.java index 349a9f447..192d30f3d 100644 --- a/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/tobemoved/HardwareEnvironment.java +++ b/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/tobemoved/HardwareEnvironment.java @@ -48,6 +48,18 @@ public String state() throws LicensingException { return new GlanceOfState(freshState()).get(); } + /** + *

+ * It's extremely important to prevent any concurrent access to the + * {@linkplain State} reading. We synchronize it by key {@code OSHI} class + * ({@linkplain SystemInfo}) lock to be sure we have exclusive access to it + * until the hardware scanning is over. + *

+ *

+ * Behind all the benefits of such a sync lock choice, it's still a foreign + * class. Just beware, in case of any threading troubles revise. + *

+ */ private State freshState() throws LicensingException { State state; synchronized (SystemInfo.class) { diff --git a/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/tobemoved/State.java b/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/tobemoved/State.java index 9145cfeeb..fb2819232 100644 --- a/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/tobemoved/State.java +++ b/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/internal/oshi/tobemoved/State.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.function.Supplier; import org.eclipse.passage.lic.internal.api.LicensingException; @@ -87,6 +88,26 @@ boolean hasValue(EnvironmentProperty property, String expected) { .orElse(false); } + Set properties() { + return hardware.keySet(); + } + + String value(EnvironmentProperty key) { + return hardware.get(key); + } + + int disksAmount() { + return disks.size(); + } + + Set diskProperties(int no) { + return disks.get(no).keySet(); + } + + String diskValue(int no, EnvironmentProperty key) { + return disks.get(no).get(key); + } + private void read() throws LicensingException { try { SystemInfo system = new SystemInfo(); diff --git a/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/oshi/OshiHal.java b/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/oshi/OshiHal.java index b01d907e8..3c1d6da5a 100644 --- a/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/oshi/OshiHal.java +++ b/bundles/org.eclipse.passage.lic.oshi/src/org/eclipse/passage/lic/oshi/OshiHal.java @@ -19,7 +19,12 @@ import java.util.Set; import org.eclipse.passage.lic.api.inspector.HardwareInspector; +import org.eclipse.passage.lic.internal.oshi.tobemoved.HardwareEnvironment; +/** + * @deprecated use 1.0 {@link HardwareEnvironment}'s state + */ +@Deprecated public class OshiHal { public static final String CONDITION_TYPE_HARDWARE = "hardware"; //$NON-NLS-1$ diff --git a/bundles/org.eclipse.passage.seal.demo/META-INF/MANIFEST.MF b/bundles/org.eclipse.passage.seal.demo/META-INF/MANIFEST.MF index 3d73a1272..fee140962 100644 --- a/bundles/org.eclipse.passage.seal.demo/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.passage.seal.demo/META-INF/MANIFEST.MF @@ -14,7 +14,8 @@ Require-Bundle: org.eclipse.osgi.services;bundle-version="3.8.0", org.eclipse.passage.lic.hc;bundle-version="0.5.300", org.eclipse.passage.lic.json;bundle-version="0.5.300", org.eclipse.passage.lic.bc;bundle-version="0.5.100", - org.eclipse.passage.lic.licenses.migration + org.eclipse.passage.lic.licenses.migration, + org.eclipse.passage.lic.oshi Service-Component: OSGI-INF/*.xml Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.passage.seal.internal.demo;x-internal:=true diff --git a/bundles/org.eclipse.passage.seal.demo/src/org/eclipse/passage/seal/internal/demo/SealedAccessCycleConfiguration.java b/bundles/org.eclipse.passage.seal.demo/src/org/eclipse/passage/seal/internal/demo/SealedAccessCycleConfiguration.java index a24495e89..15b813274 100644 --- a/bundles/org.eclipse.passage.seal.demo/src/org/eclipse/passage/seal/internal/demo/SealedAccessCycleConfiguration.java +++ b/bundles/org.eclipse.passage.seal.demo/src/org/eclipse/passage/seal/internal/demo/SealedAccessCycleConfiguration.java @@ -20,20 +20,22 @@ import org.eclipse.passage.lic.internal.api.LicensedProduct; import org.eclipse.passage.lic.internal.api.LicensingException; import org.eclipse.passage.lic.internal.api.conditions.EvaluationType; -import org.eclipse.passage.lic.internal.api.conditions.evaluation.PermissionEmittingService; -import org.eclipse.passage.lic.internal.api.conditions.evaluation.PermissionEmittersRegistry; import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionEvaluationService; import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionEvaluatorsRegistry; -import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionProtocol; -import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionPasringRegistry; import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionParsingService; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionPasringRegistry; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionProtocol; import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionTokenAssessmentService; import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionTokenAssessorsRegistry; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.PermissionEmittersRegistry; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.PermissionEmittingService; import org.eclipse.passage.lic.internal.api.conditions.mining.ConditionTransport; import org.eclipse.passage.lic.internal.api.conditions.mining.ConditionTransportRegistry; import org.eclipse.passage.lic.internal.api.conditions.mining.ContentType; import org.eclipse.passage.lic.internal.api.conditions.mining.MinedConditions; import org.eclipse.passage.lic.internal.api.conditions.mining.MinedConditionsRegistry; +import org.eclipse.passage.lic.internal.api.inspection.RuntimeEnvironment; +import org.eclipse.passage.lic.internal.api.inspection.RuntimeEnvironmentRegistry; import org.eclipse.passage.lic.internal.api.io.KeyKeeper; import org.eclipse.passage.lic.internal.api.io.KeyKeeperRegistry; import org.eclipse.passage.lic.internal.api.io.StreamCodec; @@ -42,8 +44,8 @@ import org.eclipse.passage.lic.internal.api.registry.StringServiceId; import org.eclipse.passage.lic.internal.api.requirements.ResolvedRequirements; import org.eclipse.passage.lic.internal.api.requirements.ResolvedRequirementsRegistry; -import org.eclipse.passage.lic.internal.base.conditions.evaluation.BasePermissionEmittingService; import org.eclipse.passage.lic.internal.base.conditions.evaluation.AndsProtocolExpressionParseService; +import org.eclipse.passage.lic.internal.base.conditions.evaluation.BasePermissionEmittingService; import org.eclipse.passage.lic.internal.base.conditions.evaluation.SimpleMapExpressionEvaluationService; import org.eclipse.passage.lic.internal.base.conditions.mining.MiningEquipment; import org.eclipse.passage.lic.internal.base.conditions.mining.UserHomeResidentConditions; @@ -57,6 +59,8 @@ import org.eclipse.passage.lic.internal.hc.remote.impl.RemoteConditions; import org.eclipse.passage.lic.internal.json.tobemoved.JsonConditionTransport; import org.eclipse.passage.lic.internal.licenses.migration.tobemoved.XmiConditionTransport; +import org.eclipse.passage.lic.internal.oshi.tobemoved.HardwareAssessmentService; +import org.eclipse.passage.lic.internal.oshi.tobemoved.HardwareEnvironment; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkUtil; @@ -72,7 +76,8 @@ final class SealedAccessCycleConfiguration implements AccessCycleConfiguration { private final Registry emitters; private final Registry expressionParsers; private final Registry expressionEvaluators; - private final Registry tokenEvaluators; + private final Registry tokenAssessors; + private final Registry environments; SealedAccessCycleConfiguration(Supplier product) { alarm = LicensingException::printStackTrace; @@ -114,8 +119,11 @@ final class SealedAccessCycleConfiguration implements AccessCycleConfiguration { expressionEvaluators = new ReadOnlyRegistry<>(Arrays.asList(// new SimpleMapExpressionEvaluationService()// )); - tokenEvaluators = new ReadOnlyRegistry<>(Arrays.asList(// - // FIXME: OSHI-based evaluator for EvaluationType.Hardware + tokenAssessors = new ReadOnlyRegistry<>(Arrays.asList(// + new HardwareAssessmentService(environments())// + )); + environments = new ReadOnlyRegistry<>(Arrays.asList(// + new HardwareEnvironment()// )); } @@ -165,7 +173,12 @@ public ExpressionEvaluatorsRegistry expressionEvaluators() { @Override public ExpressionTokenAssessorsRegistry expressionAssessors() { - return () -> tokenEvaluators; + return () -> tokenAssessors; + } + + @Override + public RuntimeEnvironmentRegistry environments() { + return () -> environments; } } diff --git a/tests/org.eclipse.passage.lic.api.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.passage.lic.api.tests/META-INF/MANIFEST.MF index 14de1ee60..54bc9ed2b 100644 --- a/tests/org.eclipse.passage.lic.api.tests/META-INF/MANIFEST.MF +++ b/tests/org.eclipse.passage.lic.api.tests/META-INF/MANIFEST.MF @@ -17,7 +17,9 @@ Export-Package: org.eclipse.passage.lic.api.tests;x-internal:=true, org.eclipse.passage.lic.api.tests.fakes.conditions.evaluation, org.eclipse.passage.lic.api.tests.fakes.conditions.mining;x-internal:=true, org.eclipse.passage.lic.api.tests.fakes.diagnostic;x-internal:=true, + org.eclipse.passage.lic.api.tests.fakes.inspection;x-internal:=true, org.eclipse.passage.lic.api.tests.fakes.io;x-internal:=true, org.eclipse.passage.lic.api.tests.fakes.requirements;x-internal:=true, + org.eclipse.passage.lic.api.tests.inspection;x-internal:=true, org.eclipse.passage.lic.api.tests.registry;x-internal:=true, org.eclipse.passage.lic.api.tests.version;x-internal:=true diff --git a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/FrameworkContractTest.java b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/FrameworkContractTest.java index f67bed5bd..67efaee19 100644 --- a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/FrameworkContractTest.java +++ b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/FrameworkContractTest.java @@ -21,10 +21,10 @@ import org.eclipse.passage.lic.internal.api.Framework; import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionProtocol; import org.eclipse.passage.lic.internal.api.conditions.mining.ContentType; +import org.eclipse.passage.lic.internal.api.inspection.RuntimeEnvironmentRegistry; import org.eclipse.passage.lic.internal.api.registry.Registry; import org.eclipse.passage.lic.internal.api.registry.Service; import org.eclipse.passage.lic.internal.api.registry.ServiceId; -import org.junit.Ignore; import org.junit.Test; /** @@ -147,7 +147,6 @@ public final void hasEvaluatorForDefaultExpressionFormat() { } @Test - @Ignore // yet to be implemented (OSHI-based) public final void canAssessConditionExpressionsSegment() { assertServiceRegistryIsFunctional(config().expressionAssessors().get()); } @@ -157,6 +156,19 @@ public final void prohibitsExpressionSegmentAssessmentServicesExtension() { assertTrue(readOnly(config().expressionAssessors().get())); } + @Test + public final void hasRuntimeEnvironmentInspectorsRegistry() { + RuntimeEnvironmentRegistry environments = framework().get().accessCycleConfiguration().environments(); + assertNotNull(environments); + assertNotNull(environments.get()); + assertNotNull(environments.get().services()); // can legally be empty + } + + @Test + public final void prohibitsRuntimeEnvironmentInspectionServicesExtension() { + assertTrue(readOnly(config().expressionAssessors().get())); + } + private > void assertServiceRegistryIsFunctional( Registry registry) { assertNotNull(registry); diff --git a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/RuntimeEnvironmentRegitryTest.java b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/RuntimeEnvironmentRegitryTest.java new file mode 100644 index 000000000..f8e489404 --- /dev/null +++ b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/RuntimeEnvironmentRegitryTest.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2020 ArSysOp + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0/. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * ArSysOp - initial API and implementation + *******************************************************************************/ +package org.eclipse.passage.lic.api.tests; + +import java.util.Collection; +import java.util.Optional; +import java.util.function.Supplier; + +import org.eclipse.passage.lic.api.tests.fakes.inspection.FakeRuntimeEnvironment; +import org.eclipse.passage.lic.internal.api.Framework; +import org.eclipse.passage.lic.internal.api.inspection.RuntimeEnvironment; + +/** + *

+ * Check that {@linkplain Framework} instance in use supplies read only + * collection of runtime environment inspection services. + *

+ *

+ * Each {@code Framework} implementation must extend this class and satisfy all + * the demands. + *

+ */ +@SuppressWarnings("restriction") +public abstract class RuntimeEnvironmentRegitryTest extends ReadOnlyCollectionTest { + + @Override + protected final Supplier> collection() { + return () -> framework().get().accessCycleConfiguration().environments().get().services(); + } + + @Override + protected final RuntimeEnvironment single() { + return new FakeRuntimeEnvironment(); + } + + protected abstract Optional framework(); + +} diff --git a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/StreamCodecsRegitryTest.java b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/StreamCodecsRegitryTest.java index 812d5ee7c..7d910d18b 100644 --- a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/StreamCodecsRegitryTest.java +++ b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/StreamCodecsRegitryTest.java @@ -23,7 +23,7 @@ /** *

* Check that {@linkplain Framework} instance in use supplies read only - * collection of sream codecs. + * collection of stream codecs. *

*

* Each {@code Framework} implementation must extend this class and satisfy all diff --git a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/fakes/inspection/FakeRuntimeEnvironment.java b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/fakes/inspection/FakeRuntimeEnvironment.java new file mode 100644 index 000000000..bded2fde6 --- /dev/null +++ b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/fakes/inspection/FakeRuntimeEnvironment.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2020 ArSysOp + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0/. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * ArSysOp - initial API and implementation + *******************************************************************************/ +package org.eclipse.passage.lic.api.tests.fakes.inspection; + +import org.eclipse.passage.lic.internal.api.LicensingException; +import org.eclipse.passage.lic.internal.api.conditions.EvaluationType; +import org.eclipse.passage.lic.internal.api.inspection.EnvironmentProperty; +import org.eclipse.passage.lic.internal.api.inspection.RuntimeEnvironment; + +@SuppressWarnings("restriction") +public final class FakeRuntimeEnvironment implements RuntimeEnvironment { + + @Override + public EvaluationType id() { + throw new UnsupportedOperationException(); + } + + @Override + public String state() throws LicensingException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isAssuptionTrue(EnvironmentProperty property, String value) throws LicensingException { + throw new UnsupportedOperationException(); + } + +} diff --git a/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/inspection/RuntimeEnvironmentContractTest.java b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/inspection/RuntimeEnvironmentContractTest.java new file mode 100644 index 000000000..3196d5222 --- /dev/null +++ b/tests/org.eclipse.passage.lic.api.tests/src/org/eclipse/passage/lic/api/tests/inspection/RuntimeEnvironmentContractTest.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright (c) 2020 ArSysOp + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0/. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * ArSysOp - initial API and implementation + *******************************************************************************/ +package org.eclipse.passage.lic.api.tests.inspection; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.eclipse.passage.lic.internal.api.LicensingException; +import org.eclipse.passage.lic.internal.api.conditions.EvaluationType; +import org.eclipse.passage.lic.internal.api.inspection.EnvironmentProperty; +import org.eclipse.passage.lic.internal.api.inspection.RuntimeEnvironment; +import org.junit.Test; + +@SuppressWarnings("restriction") +public abstract class RuntimeEnvironmentContractTest { + @Test + public void isDedicatedToProperEvaluationType() { + assertEquals(expectedEvaluationType(), environment().id()); + } + + @Test + public void inspects() { + try { + assertFalse(environment().isAssuptionTrue(property(), invalidPropertyValue())); + } catch (LicensingException e) { + fail("Is not supposed to fail on valid data"); //$NON-NLS-1$ + } + } + + @Test(expected = NullPointerException.class) + public void doesNotInspectNullProperty() { + try { + environment().isAssuptionTrue(null, "none"); //$NON-NLS-1$ + } catch (LicensingException e) { + fail("No insection activity is intended to be triggered for invalid input data"); //$NON-NLS-1$ + } + } + + @Test(expected = NullPointerException.class) + public void doesNotInspectForNullValue() { + try { + environment().isAssuptionTrue(property(), null); // $NON-NLS-1$ + } catch (LicensingException e) { + fail("No insection activity is intended to be triggered for invalid input data"); //$NON-NLS-1$ + } + } + + @Test + public void knowsSimpleRegexp() { + try { + assertTrue(environment().isAssuptionTrue(property(), "*"));//$NON-NLS-1$ + } catch (LicensingException e) { + fail("Is not supposed to fail on valid data"); //$NON-NLS-1$ + } + } + + @Test + public void depictsState() { + try { + String state = environment().state(); + assertNotNull(state); + assertFalse(state.trim().isEmpty()); + } catch (LicensingException e) { + fail("In not intended to fail"); //$NON-NLS-1$ + } + } + + @Test + public void standsSimultaneousRequests() { + // given: single instance of the env and lots of requesters + RuntimeEnvironment environment = environment(); + int threads = 128; + CountDownLatch readySteadyGo = new CountDownLatch(1); + CountDownLatch done = new CountDownLatch(threads); + List demands = IntStream.range(0, threads) // + .mapToObj(no -> new InspectionDemand(environment, readySteadyGo, done))// + .collect(Collectors.toList()); + + // when: run all of the requesters simultaneously (latched by readySteadyGo) + Executor executor = Executors.newFixedThreadPool(threads); + demands.stream().forEach(executor::execute); + try { + Thread.sleep(2000); // let'em all start and hold waiting for each other + readySteadyGo.countDown(); // and now trigger'em all to ddos the env + done.await(); // and just wait until each of'em finish + } catch (InterruptedException e) { + fail("Test has been interrupted"); //$NON-NLS-1$ + } + + // then: all of'em succeed + assertTrue(demands.stream().allMatch(InspectionDemand::result)); + } + + private final class InspectionDemand implements Runnable { + private final CountDownLatch altogether; + private final CountDownLatch done; + private final RuntimeEnvironment env; + private boolean result = false; + + InspectionDemand(RuntimeEnvironment env, CountDownLatch altogether, CountDownLatch done) { + this.env = env; + this.altogether = altogether; + this.done = done; + } + + @Override + public void run() { + try { + altogether.await(); // wait for a common signal to start simultaneously + ask(); + done.countDown(); // report you are done + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + + private void ask() { + try { + result = !env.isAssuptionTrue(property(), invalidPropertyValue()); + } catch (Exception e) { + result = false; + } + } + + boolean result() { + return result; + } + } + + protected abstract RuntimeEnvironment environment(); + + protected abstract EvaluationType expectedEvaluationType(); + + protected abstract String invalidPropertyValue(); + + protected abstract EnvironmentProperty property(); + +} diff --git a/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/tests/requirements/SabotagedFramework.java b/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/tests/requirements/SabotagedFramework.java index 265f7b4e1..c037795c4 100644 --- a/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/tests/requirements/SabotagedFramework.java +++ b/tests/org.eclipse.passage.lic.base.tests/src/org/eclipse/passage/lic/internal/base/tests/requirements/SabotagedFramework.java @@ -17,12 +17,13 @@ import org.eclipse.passage.lic.internal.api.AccessCycleConfiguration; import org.eclipse.passage.lic.internal.api.Framework; import org.eclipse.passage.lic.internal.api.LicensedProduct; -import org.eclipse.passage.lic.internal.api.conditions.evaluation.PermissionEmittersRegistry; import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionEvaluatorsRegistry; import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionPasringRegistry; import org.eclipse.passage.lic.internal.api.conditions.evaluation.ExpressionTokenAssessorsRegistry; +import org.eclipse.passage.lic.internal.api.conditions.evaluation.PermissionEmittersRegistry; import org.eclipse.passage.lic.internal.api.conditions.mining.ConditionTransportRegistry; import org.eclipse.passage.lic.internal.api.conditions.mining.MinedConditionsRegistry; +import org.eclipse.passage.lic.internal.api.inspection.RuntimeEnvironmentRegistry; import org.eclipse.passage.lic.internal.api.io.KeyKeeperRegistry; import org.eclipse.passage.lic.internal.api.io.StreamCodecRegistry; import org.eclipse.passage.lic.internal.api.registry.Registry; @@ -98,6 +99,11 @@ public ExpressionTokenAssessorsRegistry expressionAssessors() { return () -> noService(); } + @Override + public RuntimeEnvironmentRegistry environments() { + return () -> noService(); + } + } } diff --git a/tests/org.eclipse.passage.lic.oshi.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.passage.lic.oshi.tests/META-INF/MANIFEST.MF index 45f7336fd..6ef77b0cf 100644 --- a/tests/org.eclipse.passage.lic.oshi.tests/META-INF/MANIFEST.MF +++ b/tests/org.eclipse.passage.lic.oshi.tests/META-INF/MANIFEST.MF @@ -14,4 +14,5 @@ Require-Bundle: org.junit;bundle-version="4.12.0", org.eclipse.osgi.services;bundle-version="0.0.0", org.eclipse.passage.lic.api;bundle-version="0.0.0", org.eclipse.passage.lic.base;bundle-version="0.0.0", - org.eclipse.passage.lic.oshi;bundle-version="0.0.0" + org.eclipse.passage.lic.oshi;bundle-version="0.0.0", + org.eclipse.passage.lic.api.tests diff --git a/tests/org.eclipse.passage.lic.oshi.tests/src/org/eclipse/passage/lic/oshi/tests/tobemoved/HardwareEnvironmentTest.java b/tests/org.eclipse.passage.lic.oshi.tests/src/org/eclipse/passage/lic/oshi/tests/tobemoved/HardwareEnvironmentTest.java index 5f04a9ab2..c55fb5338 100644 --- a/tests/org.eclipse.passage.lic.oshi.tests/src/org/eclipse/passage/lic/oshi/tests/tobemoved/HardwareEnvironmentTest.java +++ b/tests/org.eclipse.passage.lic.oshi.tests/src/org/eclipse/passage/lic/oshi/tests/tobemoved/HardwareEnvironmentTest.java @@ -12,131 +12,34 @@ *******************************************************************************/ package org.eclipse.passage.lic.oshi.tests.tobemoved; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import org.eclipse.passage.lic.internal.api.LicensingException; +import org.eclipse.passage.lic.api.tests.inspection.RuntimeEnvironmentContractTest; import org.eclipse.passage.lic.internal.api.conditions.EvaluationType; -import org.eclipse.passage.lic.internal.base.inspection.hardware.Disk; +import org.eclipse.passage.lic.internal.api.inspection.RuntimeEnvironment; import org.eclipse.passage.lic.internal.base.inspection.hardware.OS; +import org.eclipse.passage.lic.internal.base.inspection.hardware.OS.Family; import org.eclipse.passage.lic.internal.oshi.tobemoved.HardwareEnvironment; -import org.junit.Test; @SuppressWarnings("restriction") -public final class HardwareEnvironmentTest { - - @Test - public void isDedicatedToHardware() { - assertEquals(new EvaluationType.Hardware(), new HardwareEnvironment().id()); - } - - @Test - public void inspects() { - try { - assertFalse(new HardwareEnvironment().isAssuptionTrue(// - new OS.Family(), // - "not-existing-operating-system")); //$NON-NLS-1$ - } catch (LicensingException e) { - fail("Is not supposed to fail on valid data"); //$NON-NLS-1$ - } - } - - @Test(expected = NullPointerException.class) - public void doesNotInspectNullProperty() { - try { - new HardwareEnvironment().isAssuptionTrue(null, "none"); //$NON-NLS-1$ - } catch (LicensingException e) { - fail("No insection activity is intended to be triggered for invalid input data"); //$NON-NLS-1$ - } - } +public final class HardwareEnvironmentTest extends RuntimeEnvironmentContractTest { - @Test(expected = NullPointerException.class) - public void doesNotInspectForNullValue() { - try { - new HardwareEnvironment().isAssuptionTrue(new OS.Family(), null); // $NON-NLS-1$ - } catch (LicensingException e) { - fail("No insection activity is intended to be triggered for invalid input data"); //$NON-NLS-1$ - } + @Override + protected RuntimeEnvironment environment() { + return new HardwareEnvironment(); } - @Test - public void knowsSimpleRegexp() { - try { - assertTrue(new HardwareEnvironment().isAssuptionTrue(new OS.Family(), "*"));//$NON-NLS-1$ - } catch (LicensingException e) { - fail("Is not supposed to fail on valid data"); //$NON-NLS-1$ - } + @Override + protected EvaluationType expectedEvaluationType() { + return new EvaluationType.Hardware(); } - @Test - public void standsSimultaneousRequests() { - // given: single instance of the env and lots of requesters - HardwareEnvironment hardware = new HardwareEnvironment(); - int threads = 128; - CountDownLatch readySteadyGo = new CountDownLatch(1); - CountDownLatch done = new CountDownLatch(threads); - List demands = IntStream.range(0, threads) // - .mapToObj(no -> new InspectionDemand(hardware, readySteadyGo, done, no))// - .collect(Collectors.toList()); - - // when: run all of the requesters simultaneously (latched by readySteadyGo) - Executor executor = Executors.newFixedThreadPool(threads); - demands.stream().forEach(executor::execute); - try { - Thread.sleep(2000); // let'em all start and hold waiting for each other - readySteadyGo.countDown(); // and now trigger'em all to ddos the env - done.await(); // and just wait until each of'em finish - } catch (InterruptedException e) { - fail("Test has been interrupted"); //$NON-NLS-1$ - } - - // then: all of'em succeed - assertTrue(demands.stream().allMatch(InspectionDemand::result)); + @Override + protected String invalidPropertyValue() { + return "not-existing-operating-system"; //$NON-NLS-1$ } - private static final class InspectionDemand implements Runnable { - private final CountDownLatch altogether; - private final CountDownLatch done; - private final HardwareEnvironment env; - private boolean result = false; - - InspectionDemand(HardwareEnvironment env, CountDownLatch altogether, CountDownLatch done, int no) { - this.env = env; - this.altogether = altogether; - this.done = done; - } - - @Override - public void run() { - try { - altogether.await(); // wait for a common signal to start simultaneously - ask(); - done.countDown(); // report you are done - } catch (InterruptedException ex) { - ex.printStackTrace(); - } - } - - private void ask() { - try { - result = !env.isAssuptionTrue(new Disk.Serial(), "not-existing-disk-serial"); //$NON-NLS-1$ - } catch (Exception e) { - result = false; - } - } - - boolean result() { - return result; - } + @Override + protected Family property() { + return new OS.Family(); } } diff --git a/tests/org.eclipse.passage.seal.demo.tests/src/org/eclipse/passage/seal/demo/tests/registries/SealedRuntimeEnvironmentRegistryTest.java b/tests/org.eclipse.passage.seal.demo.tests/src/org/eclipse/passage/seal/demo/tests/registries/SealedRuntimeEnvironmentRegistryTest.java new file mode 100644 index 000000000..1f86dfab3 --- /dev/null +++ b/tests/org.eclipse.passage.seal.demo.tests/src/org/eclipse/passage/seal/demo/tests/registries/SealedRuntimeEnvironmentRegistryTest.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2020 ArSysOp + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0/. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * ArSysOp - initial API and implementation + *******************************************************************************/ +package org.eclipse.passage.seal.demo.tests.registries; + +import java.util.Optional; + +import org.eclipse.passage.lic.api.tests.RuntimeEnvironmentRegitryTest; +import org.eclipse.passage.lic.internal.api.Framework; +import org.eclipse.passage.seal.internal.demo.DemoFrameworkSupplier; + +@SuppressWarnings("restriction") +public final class SealedRuntimeEnvironmentRegistryTest extends RuntimeEnvironmentRegitryTest { + + @Override + protected Optional framework() { + return new DemoFrameworkSupplier().get(); + } + +}