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,59 @@
<!--
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
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-repository</artifactId>
<version>0.2.0-SNAPSHOT</version>
</parent>
<artifactId>hawkbit-repository-test</artifactId>
<name>hawkBit :: Repository Test Utilities</name>
<dependencies>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-repository-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-repository-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-artifact-repository-mongo</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
</dependency>
<dependency>
<groupId>net._01001111</groupId>
<artifactId>jlorem</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
</dependencies>
</project>

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 {};
}