refactored test data generation. Refactored entity factor methods.

Signed-off-by: Kai Zimmermann <kai.zimmermann@bosch-si.com>
This commit is contained in:
Kai Zimmermann
2016-05-31 08:51:49 +02:00
parent a4e0fc2457
commit 7a98c58407
137 changed files with 2937 additions and 2593 deletions

View File

@@ -0,0 +1,214 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.util;
import org.eclipse.hawkbit.ExcludePathAwareShallowETagFilter;
import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.Constants;
import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
import org.eclipse.hawkbit.repository.RolloutManagement;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.repository.TagManagement;
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.security.DosFilter;
import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.MethodRule;
import org.junit.rules.TestWatchman;
import org.junit.runner.RunWith;
import org.junit.runners.model.FrameworkMethod;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.data.auditing.AuditingHandler;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ActiveProfiles({ "test" })
@WithUser(principal = "bumlux", allSpPermissions = true, authorities = "ROLE_CONTROLLER")
// destroy the context after each test class because otherwise we get problem
// when context is
// refreshed we e.g. get two instances of CacheManager which leads to very
// strange test failures.
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
public abstract class AbstractIntegrationTest implements EnvironmentAware {
protected static Logger LOG = null;
protected static final Pageable pageReq = new PageRequest(0, 400);
/**
* Number of {@link DistributionSetType}s that exist in every test case. One
* generated by using
* {@link TestdataFactory#findOrCreateDefaultTestDsType()} and two
* {@link SystemManagement#getTenantMetadata()};
*/
protected static final int DEFAULT_DS_TYPES = Constants.DEFAULT_DS_TYPES_IN_TENANT + 1;
@Autowired
protected EntityFactory entityFactory;
@Autowired
protected SoftwareManagement softwareManagement;
@Autowired
protected DistributionSetManagement distributionSetManagement;
@Autowired
protected ControllerManagement controllerManagement;
@Autowired
protected TargetManagement targetManagement;
@Autowired
protected TargetFilterQueryManagement targetFilterQueryManagement;
@Autowired
protected TagManagement tagManagement;
@Autowired
protected DeploymentManagement deploymentManagement;
@Autowired
protected ArtifactManagement artifactManagement;
@Autowired
protected WebApplicationContext context;
@Autowired
protected ControllerManagement controllerManagament;
@Autowired
protected AuditingHandler auditingHandler;
@Autowired
protected TenantAware tenantAware;
@Autowired
protected SystemManagement systemManagement;
@Autowired
protected TenantConfigurationManagement tenantConfigurationManagement;
@Autowired
protected RolloutManagement rolloutManagement;
@Autowired
protected RolloutGroupManagement rolloutGroupManagement;
@Autowired
protected SystemSecurityContext systemSecurityContext;
@Autowired
protected TestRepositoryManagement testRepositoryManagement;
protected MockMvc mvc;
protected SoftwareModuleType osType;
protected SoftwareModuleType appType;
protected SoftwareModuleType runtimeType;
protected DistributionSetType standardDsType;
@Autowired
protected TestdataFactory testdataFactory;
@Rule
public final WithSpringAuthorityRule securityRule = new WithSpringAuthorityRule();
protected Environment environment = null;
@Override
public void setEnvironment(final Environment environment) {
this.environment = environment;
}
@Before
public void before() throws Exception {
mvc = createMvcWebAppContext().build();
final String description = "Updated description to have lastmodified available in tests";
osType = securityRule
.runAsPrivileged(() -> testdataFactory.findOrCreateSoftwareModuleType(TestdataFactory.SM_TYPE_OS));
osType.setDescription(description);
osType = securityRule.runAsPrivileged(() -> softwareManagement.updateSoftwareModuleType(osType));
appType = securityRule.runAsPrivileged(
() -> testdataFactory.findOrCreateSoftwareModuleType(TestdataFactory.SM_TYPE_APP, Integer.MAX_VALUE));
appType.setDescription(description);
appType = securityRule.runAsPrivileged(() -> softwareManagement.updateSoftwareModuleType(appType));
runtimeType = securityRule
.runAsPrivileged(() -> testdataFactory.findOrCreateSoftwareModuleType(TestdataFactory.SM_TYPE_RT));
runtimeType.setDescription(description);
runtimeType = securityRule.runAsPrivileged(() -> softwareManagement.updateSoftwareModuleType(runtimeType));
standardDsType = securityRule.runAsPrivileged(() -> testdataFactory.findOrCreateDefaultTestDsType());
}
@After
public void after() {
testRepositoryManagement.clearTestRepository();
}
protected DefaultMockMvcBuilder createMvcWebAppContext() {
return MockMvcBuilders.webAppContextSetup(context)
.addFilter(new DosFilter(100, 10, "127\\.0\\.0\\.1|\\[0:0:0:0:0:0:0:1\\]", "(^192\\.168\\.)",
"X-Forwarded-For"))
.addFilter(new ExcludePathAwareShallowETagFilter(
"/rest/v1/softwaremodules/{smId}/artifacts/{artId}/download", "/*/controller/artifacts/**"));
}
@Rule
public MethodRule watchman = new TestWatchman() {
@Override
public void starting(final FrameworkMethod method) {
if (LOG != null) {
LOG.info("Starting Test {}...", method.getName());
}
}
@Override
public void succeeded(final FrameworkMethod method) {
if (LOG != null) {
LOG.info("Test {} succeeded.", method.getName());
}
}
@Override
public void failed(final Throwable e, final FrameworkMethod method) {
if (LOG != null) {
LOG.error("Test {} failed with {}.", method.getName(), e);
}
}
};
}

View File

@@ -0,0 +1,110 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.util;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsOperations;
import de.flapdoodle.embed.mongo.Command;
import de.flapdoodle.embed.mongo.MongodExecutable;
import de.flapdoodle.embed.mongo.MongodStarter;
import de.flapdoodle.embed.mongo.config.ArtifactStoreBuilder;
import de.flapdoodle.embed.mongo.config.DownloadConfigBuilder;
import de.flapdoodle.embed.mongo.config.IMongodConfig;
import de.flapdoodle.embed.mongo.config.MongodConfigBuilder;
import de.flapdoodle.embed.mongo.config.Net;
import de.flapdoodle.embed.mongo.config.RuntimeConfigBuilder;
import de.flapdoodle.embed.mongo.distribution.Version;
import de.flapdoodle.embed.process.config.store.HttpProxyFactory;
import de.flapdoodle.embed.process.runtime.Network;
/**
* Test class that contains MonfoDb start and stop for the test
*
*
*
*
*/
public abstract class AbstractIntegrationTestWithMongoDB extends AbstractIntegrationTest {
protected static volatile MongodExecutable mongodExecutable = null;
private static final AtomicInteger mongoLease = new AtomicInteger(0);
private static volatile Integer port;
@Autowired
protected GridFsOperations operations;
@BeforeClass
public static void setupMongo() throws UnknownHostException, IOException {
mongoLease.incrementAndGet();
if (mongodExecutable == null) {
final Command command = Command.MongoD;
final RuntimeConfigBuilder runtimeConfig = new RuntimeConfigBuilder().defaults(command);
if (port == null) {
port = new FreePortFileWriter(28017, 28090, "./target/freeports").getPort();
System.setProperty("spring.data.mongodb.port", String.valueOf(port));
}
Version version = Version.V3_0_8;
if (System.getProperty("inf.mongodb.version") != null) {
version = Version
.valueOf("V" + System.getProperty("inf.mongodb.version").trim().replaceAll("\\.", "_"));
}
if (System.getProperty("http.proxyHost") != null) {
runtimeConfig
.artifactStore(
new ArtifactStoreBuilder().defaults(command)
.download(new DownloadConfigBuilder().defaultsForCommand(command)
.proxyFactory(new HttpProxyFactory(
System.getProperty("http.proxyHost").trim(), Integer
.valueOf(System.getProperty("http.proxyPort"))))));
}
final IMongodConfig mongodConfig = new MongodConfigBuilder().version(version)
.net(new Net("127.0.0.1", port, Network.localhostIsIPv6())).build();
final MongodStarter starter = MongodStarter.getInstance(runtimeConfig.build());
mongodExecutable = starter.prepare(mongodConfig);
mongodExecutable.start();
}
}
@After
public void cleanCurrentCollection() {
operations.delete(new Query());
}
public static void internalShutDownMongo() {
if (mongodExecutable != null && mongoLease.decrementAndGet() <= 0) {
mongodExecutable.stop();
mongodExecutable = null;
}
}
@AfterClass
public static void shutdownMongo() throws UnknownHostException, IOException {
if (mongodExecutable != null && mongoLease.decrementAndGet() <= 0) {
mongodExecutable.stop();
mongodExecutable = null;
}
port = null;
}
}

View File

@@ -0,0 +1,75 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.util;
import java.io.File;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
/**
*
*
*/
public class FreePortFileWriter {
private final String filePortPath;
private final int from;
private final int to;
/**
* @param from
* @param to
*/
public FreePortFileWriter(final int from, final int to, final String filePortPath) {
this.from = from;
this.to = to;
this.filePortPath = filePortPath;
}
public int getPort() {
return findFree();
}
protected int findFree() {
for (int i = from; i <= to; i++) {
if (isFree(i)) {
return i;
}
}
throw new RuntimeException("No free port in range " + from + ":" + to);
}
boolean isFree(final int port) {
try {
final File portFile = new File(filePortPath + File.separator + port + ".port");
portFile.getParentFile().mkdirs();
if (portFile.exists()) {
return false;
} else {
boolean isFree = false;
final ServerSocket sock = new ServerSocket();
sock.setReuseAddress(true);
sock.bind(new InetSocketAddress(port));
if (portFile.createNewFile()) {
portFile.deleteOnExit();
isFree = true;
}
sock.close();
// is free:
return isFree;
// We rely on an exception thrown to determine availability or
// not availability.
}
} catch (final Exception e) {
// not free.
return false;
}
}
}

View File

@@ -0,0 +1,22 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.util;
/**
* Repository support for tests.
*
*/
@FunctionalInterface
public interface TestRepositoryManagement {
/**
* Empty the test repository.
*/
void clearTestRepository();
}

View File

@@ -0,0 +1,737 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.util;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import org.apache.commons.io.IOUtils;
import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.TagManagement;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.NamedVersionedEntity;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.springframework.beans.factory.annotation.Autowired;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import net._01001111.text.LoremIpsum;
/**
* Data generator utility for tests.
*/
public class TestdataFactory {
private static final LoremIpsum LOREM = new LoremIpsum();
/**
* default {@link Target#getControllerId()}.
*/
public static final String DEFAULT_CONTROLLER_ID = "targetExist";
/**
* Default {@link SoftwareModule#getVendor()}.
*/
public static final String DEFAULT_VENDOR = "Vendor Limited, California";
/**
* Default {@link NamedVersionedEntity#getVersion()}.
*/
public static final String DEFAULT_VERSION = "1.0";
/**
* Default {@link NamedEntity#getDescription()}.
*/
public static final String DEFAULT_DESCRIPTION = "Desc: " + LOREM.words(10);
/**
* Key of test default {@link DistributionSetType}.
*/
public static final String DS_TYPE_DEFAULT = "test_default_ds_type";
/**
* Key of test "os" {@link SoftwareModuleType} -> mandatory firmware in
* {@link #DS_TYPE_DEFAULT}.
*/
public static final String SM_TYPE_OS = "os";
/**
* Key of test "runtime" {@link SoftwareModuleType} -> optional firmware in
* {@link #DS_TYPE_DEFAULT}.
*/
public static final String SM_TYPE_RT = "runtime";
/**
* Key of test "application" {@link SoftwareModuleType} -> optional software
* in {@link #DS_TYPE_DEFAULT}.
*/
public static final String SM_TYPE_APP = "application";
@Autowired
private ControllerManagement controllerManagament;
@Autowired
private SoftwareManagement softwareManagement;
@Autowired
private DistributionSetManagement distributionSetManagement;
@Autowired
private TargetManagement targetManagement;
@Autowired
private DeploymentManagement deploymentManagement;
@Autowired
private TagManagement tagManagement;
@Autowired
private EntityFactory entityFactory;
@Autowired
private ArtifactManagement artifactManagement;
/**
* Creates {@link DistributionSet} in repository including three
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
* , {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} and
* {@link DistributionSet#isRequiredMigrationStep()} <code>false</code>.
*
* @param prefix
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
* vendor and description.
*
* @return {@link DistributionSet} entity.
*/
public DistributionSet createDistributionSet(final String prefix) {
return createDistributionSet(prefix, DEFAULT_VERSION, false);
}
/**
* Creates {@link DistributionSet} in repository including three
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
* , {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION}.
*
* @param prefix
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
* vendor and description.
* @param isRequiredMigrationStep
* for {@link DistributionSet#isRequiredMigrationStep()}
*
* @return {@link DistributionSet} entity.
*/
public DistributionSet createDistributionSet(final String prefix, final boolean isRequiredMigrationStep) {
return createDistributionSet(prefix, DEFAULT_VERSION, isRequiredMigrationStep);
}
/**
* Creates {@link DistributionSet} in repository including three
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
* , {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} and
* {@link DistributionSet#isRequiredMigrationStep()} <code>false</code>.
*
* @param prefix
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
* vendor and description.
* @param tags
* {@link DistributionSet#getTags()}
*
* @return {@link DistributionSet} entity.
*/
public DistributionSet createDistributionSet(final String prefix, final Collection<DistributionSetTag> tags) {
return createDistributionSet(prefix, DEFAULT_VERSION, tags);
}
/**
* Creates {@link DistributionSet} in repository including three
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
* , {@link #SM_TYPE_APP}.
*
* @param prefix
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
* vendor and description.
* @param version
* {@link DistributionSet#getVersion()} and
* {@link SoftwareModule#getVersion()} extended by a random
* number.
* @param isRequiredMigrationStep
* for {@link DistributionSet#isRequiredMigrationStep()}
*
* @return {@link DistributionSet} entity.
*/
public DistributionSet createDistributionSet(final String prefix, final String version,
final boolean isRequiredMigrationStep) {
final SoftwareModule appMod = softwareManagement.createSoftwareModule(entityFactory.generateSoftwareModule(
findOrCreateSoftwareModuleType(SM_TYPE_APP, Integer.MAX_VALUE), prefix + SM_TYPE_APP,
version + "." + new Random().nextInt(100), LOREM.words(20), prefix + " vendor Limited, California"));
final SoftwareModule runtimeMod = softwareManagement
.createSoftwareModule(entityFactory.generateSoftwareModule(findOrCreateSoftwareModuleType(SM_TYPE_RT),
prefix + "app runtime", version + "." + new Random().nextInt(100), LOREM.words(20),
prefix + " vendor GmbH, Stuttgart, Germany"));
final SoftwareModule osMod = softwareManagement
.createSoftwareModule(entityFactory.generateSoftwareModule(findOrCreateSoftwareModuleType(SM_TYPE_OS),
prefix + " Firmware", version + "." + new Random().nextInt(100), LOREM.words(20),
prefix + " vendor Limited Inc, California"));
return distributionSetManagement
.createDistributionSet(generateDistributionSet(prefix != null && prefix.length() > 0 ? prefix : "DS",
version, findOrCreateDefaultTestDsType(), Lists.newArrayList(osMod, runtimeMod, appMod))
.setRequiredMigrationStep(isRequiredMigrationStep));
}
/**
* Creates {@link DistributionSet} in repository including three
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
* , {@link #SM_TYPE_APP}.
*
* @param prefix
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
* vendor and description.
* @param version
* {@link DistributionSet#getVersion()} and
* {@link SoftwareModule#getVersion()} extended by a random
* number.
* @param tags
* {@link DistributionSet#getTags()}
*
* @return {@link DistributionSet} entity.
*/
public DistributionSet createDistributionSet(final String prefix, final String version,
final Collection<DistributionSetTag> tags) {
final DistributionSet set = createDistributionSet(prefix, version, false);
final List<DistributionSet> sets = new ArrayList<>();
sets.add(set);
tags.forEach(tag -> distributionSetManagement.toggleTagAssignment(sets, tag));
return distributionSetManagement.findDistributionSetById(set.getId());
}
/**
* Creates {@link DistributionSet}s in repository including three
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
* , {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} followed by an
* iterative number and {@link DistributionSet#isRequiredMigrationStep()}
* <code>false</code>.
*
* @param number
* of {@link DistributionSet}s to create
*
* @return {@link List} of {@link DistributionSet} entities
*/
public List<DistributionSet> createDistributionSets(final int number) {
return createDistributionSets("", number);
}
/**
* Creates {@link DistributionSet}s in repository including three
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
* , {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} followed by an
* iterative number and {@link DistributionSet#isRequiredMigrationStep()}
* <code>false</code>.
*
* @param prefix
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
* vendor and description.
* @param number
* of {@link DistributionSet}s to create
*
* @return {@link List} of {@link DistributionSet} entities
*/
public List<DistributionSet> createDistributionSets(final String prefix, final int number) {
final List<DistributionSet> sets = new ArrayList<>();
for (int i = 0; i < number; i++) {
sets.add(createDistributionSet(prefix, DEFAULT_VERSION + "." + i, false));
}
return sets;
}
/**
* Creates {@link DistributionSet}s in repository with
* {@link #DEFAULT_DESCRIPTION} and
* {@link DistributionSet#isRequiredMigrationStep()} <code>false</code>.
*
* @param name
* {@link DistributionSet#getName()}
* @param version
* {@link DistributionSet#getVersion()}
*
* @return {@link DistributionSet} entity
*/
public DistributionSet createDistributionSetWithNoSoftwareModules(final String name, final String version) {
final DistributionSet dis = entityFactory.generateDistributionSet();
dis.setName(name);
dis.setVersion(version);
dis.setDescription(DEFAULT_DESCRIPTION);
dis.setType(findOrCreateDefaultTestDsType());
return distributionSetManagement.createDistributionSet(dis);
}
/**
* Creates {@link LocalArtifact}s for given {@link SoftwareModule} with a
* small text payload.
*
* @param moduleId
* the {@link Artifact}s belong to.
*
* @return {@link LocalArtifact} entity.
*/
public List<LocalArtifact> createLocalArtifacts(final Long moduleId) {
final List<LocalArtifact> artifacts = new ArrayList<>();
for (int i = 0; i < 3; i++) {
final InputStream stubInputStream = IOUtils.toInputStream("some test data" + i, Charset.forName("UTF-8"));
artifacts.add(artifactManagement.createLocalArtifact(stubInputStream, moduleId, "filename" + i, false));
}
return artifacts;
}
/**
* Creates {@link SoftwareModule} with {@link #DEFAULT_VENDOR} and
* {@link #DEFAULT_VERSION} and random generated
* {@link Target#getDescription()} in the repository.
*
* @param typeKey
* of the {@link SoftwareModuleType}
*
* @return persisted {@link SoftwareModule}.
*/
public SoftwareModule createSoftwareModule(final String typeKey) {
return softwareManagement.createSoftwareModule(entityFactory.generateSoftwareModule(
findOrCreateSoftwareModuleType(typeKey), typeKey, DEFAULT_VERSION, LOREM.words(10), DEFAULT_VENDOR));
}
/**
* @return persisted {@link Target} with {@link #DEFAULT_CONTROLLER_ID}.
*/
public Target createTarget() {
return targetManagement.createTarget(entityFactory.generateTarget(DEFAULT_CONTROLLER_ID));
}
/**
* Creates {@link DistributionSet}s in repository including three
* {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT}
* , {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} followed by an
* iterative number and {@link DistributionSet#isRequiredMigrationStep()}
* <code>false</code>.
*
* @return persisted {@link DistributionSet}.
*/
public DistributionSet createTestDistributionSet() {
DistributionSet set = createDistributionSet("");
set.setVersion(DEFAULT_VERSION);
set = distributionSetManagement.updateDistributionSet(set);
set.getModules().forEach(module -> {
module.setDescription("Updated " + DEFAULT_DESCRIPTION);
softwareManagement.updateSoftwareModule(module);
});
// load also lazy stuff
set = distributionSetManagement.findDistributionSetByIdWithDetails(set.getId());
return set;
}
/**
* @return {@link DistributionSetType} with key {@link #DS_TYPE_DEFAULT} and
* {@link SoftwareModuleType}s {@link #SM_TYPE_OS},
* {@link #SM_TYPE_RT} , {@link #SM_TYPE_APP}.
*/
public DistributionSetType findOrCreateDefaultTestDsType() {
final List<SoftwareModuleType> mand = new ArrayList<>();
mand.add(findOrCreateSoftwareModuleType(SM_TYPE_OS));
final List<SoftwareModuleType> opt = new ArrayList<>();
opt.add(findOrCreateSoftwareModuleType(SM_TYPE_APP, Integer.MAX_VALUE));
opt.add(findOrCreateSoftwareModuleType(SM_TYPE_RT));
return findOrCreateDistributionSetType(DS_TYPE_DEFAULT, "OS (FW) mandatory, runtime (FW) and app (SW) optional",
mand, opt);
}
/**
* Creates {@link DistributionSetType} in repository.
*
* @param dsTypeKey
* {@link DistributionSetType#getKey()}
* @param dsTypeName
* {@link DistributionSetType#getName()}
*
* @return persisted {@link DistributionSetType}
*/
public DistributionSetType findOrCreateDistributionSetType(final String dsTypeKey, final String dsTypeName) {
final DistributionSetType findDistributionSetTypeByname = distributionSetManagement
.findDistributionSetTypeByKey(dsTypeKey);
if (findDistributionSetTypeByname != null) {
return findDistributionSetTypeByname;
}
final DistributionSetType type = entityFactory.generateDistributionSetType(dsTypeKey, dsTypeName,
LOREM.words(10));
return distributionSetManagement.createDistributionSetType(type);
}
/**
* Finds {@link DistributionSetType} in repository with given
* {@link DistributionSetType#getKey()} or creates if it does not exist yet.
*
* @param dsTypeKey
* {@link DistributionSetType#getKey()}
* @param dsTypeName
* {@link DistributionSetType#getName()}
* @param mandatory
* {@link DistributionSetType#getMandatoryModuleTypes()}
* @param optional
* {@link DistributionSetType#getOptionalModuleTypes()}
*
* @return persisted {@link DistributionSetType}
*/
public DistributionSetType findOrCreateDistributionSetType(final String dsTypeKey, final String dsTypeName,
final Collection<SoftwareModuleType> mandatory, final Collection<SoftwareModuleType> optional) {
final DistributionSetType findDistributionSetTypeByname = distributionSetManagement
.findDistributionSetTypeByKey(dsTypeKey);
if (findDistributionSetTypeByname != null) {
return findDistributionSetTypeByname;
}
final DistributionSetType type = entityFactory.generateDistributionSetType(dsTypeKey, dsTypeName,
LOREM.words(10));
mandatory.forEach(type::addMandatoryModuleType);
optional.forEach(type::addOptionalModuleType);
return distributionSetManagement.createDistributionSetType(type);
}
/**
* Finds {@link SoftwareModuleType} in repository with given
* {@link SoftwareModuleType#getKey()} or creates if it does not exist yet
* with {@link SoftwareModuleType#getMaxAssignments()} = 1.
*
* @param key
* {@link SoftwareModuleType#getKey()}
*
* @return persisted {@link SoftwareModuleType}
*/
public SoftwareModuleType findOrCreateSoftwareModuleType(final String key) {
return findOrCreateSoftwareModuleType(key, 1);
}
/**
* Finds {@link SoftwareModuleType} in repository with given
* {@link SoftwareModuleType#getKey()} or creates if it does not exist yet.
*
* @param key
* {@link SoftwareModuleType#getKey()}
* @param maxAssignments
* {@link SoftwareModuleType#getMaxAssignments()}
*
* @return persisted {@link SoftwareModuleType}
*/
public SoftwareModuleType findOrCreateSoftwareModuleType(final String key, final int maxAssignments) {
final SoftwareModuleType findSoftwareModuleTypeByKey = softwareManagement.findSoftwareModuleTypeByKey(key);
if (findSoftwareModuleTypeByKey != null) {
return findSoftwareModuleTypeByKey;
}
return softwareManagement.createSoftwareModuleType(
entityFactory.generateSoftwareModuleType(key, key, LOREM.words(10), maxAssignments));
}
/**
* builder method for creating a {@link DistributionSet}.
*
* @param name
* {@link DistributionSet#getName()}
* @param version
* {@link DistributionSet#getVersion()}
* @param type
* {@link DistributionSet#getType()}
* @param modules
* {@link DistributionSet#getModules()}
*
* @return the created {@link DistributionSet}
*/
public DistributionSet generateDistributionSet(final String name, final String version,
final DistributionSetType type, final Collection<SoftwareModule> modules) {
final DistributionSet distributionSet = entityFactory.generateDistributionSet(name, version, null, type,
modules);
distributionSet.setDescription(LOREM.words(10));
return distributionSet;
}
/**
* Creates {@link DistributionSetTag}s in repository.
*
* @param number
* of {@link DistributionSetTag}s
*
* @return the persisted {@link DistributionSetTag}s
*/
public List<DistributionSetTag> createDistributionSetTags(final int number) {
final List<DistributionSetTag> result = new ArrayList<>();
for (int i = 0; i < number; i++) {
result.add(entityFactory.generateDistributionSetTag("tag" + i, "tagdesc" + i, String.valueOf(i)));
}
return tagManagement.createDistributionSetTags(result);
}
/**
* builder method for creating a single target object.
*
* @param ctrlID
* the ID of the target
* @param description
* of the target
* @return the created target object
*/
public Target generateTarget(final String ctrlID, final String description) {
return generateTarget(ctrlID, description, null);
}
/**
* Builds a single {@link Target} from the given parameters.
*
* @param ctrlID
* controllerID
* @param description
* the description of the target
* @param tags
* assigned {@link TargetTag}s
* @return the generated {@link Target}
*/
private Target generateTarget(final String ctrlID, final String description, final TargetTag[] tags) {
final Target target = entityFactory.generateTarget(ctrlID);
target.setName("Prov.Target ".concat(ctrlID));
target.setDescription(description);
if (tags != null && tags.length > 0) {
for (final TargetTag t : tags) {
target.getTags().add(t);
}
}
return target;
}
/**
* Creates {@link Target}s in repository and with
* {@link #DEFAULT_CONTROLLER_ID} as prefix for
* {@link Target#getControllerId()}.
*
* @param number
* of {@link Target}s to create
*
* @return {@link List} of {@link Target} entities
*/
public List<Target> createTargets(final int number) {
return targetManagement.createTargets(generateTargets(0, number, DEFAULT_CONTROLLER_ID));
}
/**
* Builds {@link Target} objects with given prefix for
* {@link Target#getControllerId()} followed by a number suffix.
*
* @param start
* value for the controllerId suffix
* @param numberOfTargets
* of {@link Target}s to generate
* @param controllerIdPrefix
* for {@link Target#getControllerId()} generation.
* @return list of {@link Target} objects
*/
private List<Target> generateTargets(final int start, final int numberOfTargets, final String controllerIdPrefix) {
final List<Target> targets = new ArrayList<>();
for (int i = start; i < start + numberOfTargets; i++) {
targets.add(entityFactory.generateTarget(controllerIdPrefix + i));
}
return targets;
}
/**
* Builds {@link Target} objects with given prefix for
* {@link Target#getControllerId()} followed by a number suffix starting
* with 0.
*
* @param numberOfTargets
* of {@link Target}s to generate
* @param controllerIdPrefix
* for {@link Target#getControllerId()} generation.
* @return list of {@link Target} objects
*/
public List<Target> generateTargets(final int numberOfTargets, final String controllerIdPrefix) {
return generateTargets(0, numberOfTargets, controllerIdPrefix);
}
/**
* builds a set of {@link Target} fixtures from the given parameters.
*
* @param numberOfTargets
* number of targets to create
* @param controllerIdPrefix
* prefix used for the controller ID
* @param descriptionPrefix
* prefix used for the description
* @return set of {@link Target}
*/
public List<Target> generateTargets(final int numberOfTargets, final String controllerIdPrefix,
final String descriptionPrefix) {
return generateTargets(numberOfTargets, controllerIdPrefix, descriptionPrefix, null);
}
/**
* method creates set of targets by by generating the controller ID and the
* description like: prefix + no of target.
*
* @param noOfTgts
* number of targets which should be created
* @param controllerIdPrefix
* prefix of the controllerID which is concatenated with the
* number of the target. Randomly generated if <code>null</code>.
* @param descriptionPrefix
* prefix of the target description which is concatenated with
* the number of the target
* @param tags
* tags which should be added to the created {@link Target}s
* @return set of created targets
*/
private List<Target> generateTargets(final int noOfTgts, final String controllerIdPrefix,
final String descriptionPrefix, final TargetTag[] tags) {
final List<Target> list = new ArrayList<>();
for (int i = 0; i < noOfTgts; i++) {
String ctrlID = controllerIdPrefix;
if (Strings.isNullOrEmpty(ctrlID)) {
ctrlID = UUID.randomUUID().toString();
}
ctrlID = String.format("%s-%05d", ctrlID, i);
final String description = descriptionPrefix + DEFAULT_DESCRIPTION;
final Target target = generateTarget(ctrlID, description, tags);
list.add(target);
}
return list;
}
/**
* Generates {@link TargetTag}s.
*
* @param number
* of {@link TargetTag}s to generate.
*
* @return generated {@link TargetTag}s.
*/
public List<TargetTag> generateTargetTags(final int number) {
final List<TargetTag> result = new ArrayList<>();
for (int i = 0; i < number; i++) {
result.add(entityFactory.generateTargetTag("tag" + i, "tagdesc" + i, String.valueOf(i)));
}
return result;
}
/**
* Create a set of {@link TargetTag}s.
*
* @param noOfTags
* number of {@link TargetTag}. to be created
* @param tagPrefix
* prefix for the {@link TargetTag#getName()}
* @return the created set of {@link TargetTag}s
*/
public List<TargetTag> generateTargetTags(final int noOfTags, final String tagPrefix) {
final List<TargetTag> list = new ArrayList<>();
for (int i = 0; i < noOfTags; i++) {
String tagName = "myTag";
if (!Strings.isNullOrEmpty(tagPrefix)) {
tagName = tagPrefix;
}
tagName = String.format("%s-%05d", tagName, i);
final TargetTag targetTag = entityFactory.generateTargetTag(tagName);
list.add(targetTag);
}
return list;
}
private Action sendUpdateActionStatusToTarget(final Status status, final Action updActA, final String... msgs) {
updActA.setStatus(status);
final ActionStatus statusMessages = entityFactory.generateActionStatus();
statusMessages.setAction(updActA);
statusMessages.setOccurredAt(System.currentTimeMillis());
statusMessages.setStatus(status);
for (final String msg : msgs) {
statusMessages.addMessage(msg);
}
return controllerManagament.addUpdateActionStatus(statusMessages);
}
/**
* Append {@link ActionStatus} to all {@link Action}s of given
* {@link Target}s.
*
* @param targets
* to add {@link ActionStatus}
* @param status
* to add
* @param msgs
* to add
*
* @return updated {@link Action}.
*/
public List<Action> sendUpdateActionStatusToTargets(final Collection<Target> targets, final Status status,
final String... msgs) {
final List<Action> result = new ArrayList<>();
for (final Target target : targets) {
final List<Action> findByTarget = deploymentManagement.findActionsByTarget(target);
for (final Action action : findByTarget) {
result.add(sendUpdateActionStatusToTarget(status, action, msgs));
}
}
return result;
}
}

View File

@@ -0,0 +1,278 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.util;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemManagementHolder;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
public class WithSpringAuthorityRule implements TestRule {
/*
* (non-Javadoc)
*
* @see org.junit.rules.TestRule#apply(org.junit.runners.model.Statement,
* org.junit.runner.Description)
*/
@Override
public Statement apply(final Statement base, final Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
final SecurityContext oldContext = before(description);
try {
base.evaluate();
} finally {
after(oldContext);
}
}
};
}
private SecurityContext before(final Description description) throws Throwable {
final SecurityContext oldContext = SecurityContextHolder.getContext();
WithUser annotation = description.getAnnotation(WithUser.class);
if (annotation == null) {
annotation = description.getTestClass().getAnnotation(WithUser.class);
}
if (annotation != null) {
setSecurityContext(annotation);
if (annotation.autoCreateTenant()) {
SystemManagementHolder.getInstance().getSystemManagement().getTenantMetadata(annotation.tenantId());
}
}
return oldContext;
}
/**
* @param annotation
*/
private void setSecurityContext(final WithUser annotation) {
SecurityContextHolder.setContext(new SecurityContext() {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public void setAuthentication(final Authentication authentication) {
}
@Override
public Authentication getAuthentication() {
final String[] authorities;
if (annotation.allSpPermissions()) {
authorities = getAllAuthorities(annotation.authorities(), annotation.removeFromAllPermission());
} else {
authorities = annotation.authorities();
}
final TestingAuthenticationToken testingAuthenticationToken = new TestingAuthenticationToken(
annotation.principal(), annotation.credentials(), authorities);
testingAuthenticationToken
.setDetails(new TenantAwareAuthenticationDetails(annotation.tenantId(), false));
return testingAuthenticationToken;
}
private String[] getAllAuthorities(final String[] additionalAuthorities, final String[] notInclude) {
final List<String> allPermissions = new ArrayList<>();
final Field[] declaredFields = SpPermission.class.getDeclaredFields();
for (final Field field : declaredFields) {
if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) {
field.setAccessible(true);
try {
boolean addPermission = true;
final String permissionName = (String) field.get(null);
if (notInclude != null) {
for (final String notInlcudePerm : notInclude) {
if (permissionName.equals(notInlcudePerm)) {
addPermission = false;
break;
}
}
}
if (addPermission) {
allPermissions.add(permissionName);
}
} catch (IllegalArgumentException | IllegalAccessException e) {
// nope
}
}
}
for (final String authority : additionalAuthorities) {
allPermissions.add(authority);
}
return allPermissions.toArray(new String[allPermissions.size()]);
}
});
}
private void after(final SecurityContext oldContext) {
SecurityContextHolder.setContext(oldContext);
}
/**
* @param callable
* @return
* @throws Exception
*/
public <T> T runAsPrivileged(final Callable<T> callable) throws Exception {
return runAs(privilegedUser(), callable);
}
/**
*
* @param withUser
* @param callable
* @return
* @throws Exception
*/
public <T> T runAs(final WithUser withUser, final Callable<T> callable) throws Exception {
final SecurityContext oldContext = SecurityContextHolder.getContext();
setSecurityContext(withUser);
if (withUser.autoCreateTenant()) {
SystemManagementHolder.getInstance().getSystemManagement().getTenantMetadata(withUser.tenantId());
}
try {
return callable.call();
} finally {
after(oldContext);
}
}
public static WithUser withUser(final String principal, final String... authorities) {
return withUserAndTenant(principal, "default", true, true, authorities);
}
public static WithUser withUser(final String principal, final boolean allSpPermision, final String... authorities) {
return withUserAndTenant(principal, "default", true, allSpPermision, authorities);
}
public static WithUser withUser(final boolean autoCreateTenant) {
return withUserAndTenant("bumlux", "default", autoCreateTenant, true, new String[] {});
}
public static WithUser withUserAndTenant(final String principal, final String tenant, final String... authorities) {
return withUserAndTenant(principal, tenant, true, true, new String[] {});
}
public static WithUser withUserAndTenant(final String principal, final String tenant,
final boolean autoCreateTenant, final boolean allSpPermission, final String... authorities) {
return new WithUser() {
@Override
public Class<? extends Annotation> annotationType() {
return WithUser.class;
}
@Override
public String principal() {
return principal;
}
@Override
public String credentials() {
return null;
}
@Override
public String[] authorities() {
return authorities;
}
@Override
public boolean allSpPermissions() {
return allSpPermission;
}
@Override
public String[] removeFromAllPermission() {
return null;
}
@Override
public String tenantId() {
return tenant;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.hawkbit.WithUser#autoCreateTenant()
*/
@Override
public boolean autoCreateTenant() {
return autoCreateTenant;
}
};
}
private static WithUser privilegedUser() {
return new WithUser() {
@Override
public Class<? extends Annotation> annotationType() {
return WithUser.class;
}
@Override
public String principal() {
return "bumlux";
}
@Override
public String credentials() {
return null;
}
@Override
public String[] authorities() {
return new String[] { "ROLE_CONTROLLER" };
}
@Override
public boolean allSpPermissions() {
return true;
}
@Override
public String[] removeFromAllPermission() {
return null;
}
@Override
public String tenantId() {
return "default";
}
/*
* (non-Javadoc)
*
* @see org.eclipse.hawkbit.WithUser#autoCreateTenant()
*/
@Override
public boolean autoCreateTenant() {
return true;
}
};
}
}

View File

@@ -0,0 +1,77 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.util;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation to run test classes or test methods with a specific user with
* specific permissions.
*
*
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
@Inherited
public @interface WithUser {
/**
* Gets the test principal.
*
* @return test principal
*/
String principal() default "TestPrincipal";
/**
* Gets the test credentials.
*
* @return test credentials
*/
String credentials() default "TestCredentials";
/**
* Gets the test tenant id.
*
* @return test tenant id
*/
String tenantId() default "default";
/**
* Should tenant auto created.
*
* @return <true> = auto create <false> not create
*/
boolean autoCreateTenant() default true;
/**
* Gets the test authorities.
*
* @return authorities
*/
String[] authorities() default {};
/**
* Gets the test all permissions.
*
* @return permissions
*/
boolean allSpPermissions() default false;
/**
* Gets the test removeFromAllPermission.
*
* @return removeFromAllPermission
*/
String[] removeFromAllPermission() default {};
}