Split into separate maven modules.

Signed-off-by: Kai Zimmermann <kai.zimmermann@bosch-si.com>
This commit is contained in:
Kai Zimmermann
2016-05-25 17:43:57 +02:00
parent cf450dabfa
commit f2e13b8d22
310 changed files with 647 additions and 482 deletions

View File

@@ -0,0 +1,331 @@
/**
* 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;
import static org.fest.assertions.api.Assertions.assertThat;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.eclipse.hawkbit.cache.TenantAwareCacheManager;
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.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.jpa.ActionRepository;
import org.eclipse.hawkbit.repository.jpa.ActionStatusRepository;
import org.eclipse.hawkbit.repository.jpa.DistributionSetRepository;
import org.eclipse.hawkbit.repository.jpa.DistributionSetTagRepository;
import org.eclipse.hawkbit.repository.jpa.DistributionSetTypeRepository;
import org.eclipse.hawkbit.repository.jpa.ExternalArtifactRepository;
import org.eclipse.hawkbit.repository.jpa.LocalArtifactRepository;
import org.eclipse.hawkbit.repository.jpa.RolloutGroupRepository;
import org.eclipse.hawkbit.repository.jpa.RolloutRepository;
import org.eclipse.hawkbit.repository.jpa.SoftwareModuleMetadataRepository;
import org.eclipse.hawkbit.repository.jpa.SoftwareModuleRepository;
import org.eclipse.hawkbit.repository.jpa.SoftwareModuleTypeRepository;
import org.eclipse.hawkbit.repository.jpa.TargetInfoRepository;
import org.eclipse.hawkbit.repository.jpa.TargetRepository;
import org.eclipse.hawkbit.repository.jpa.TargetTagRepository;
import org.eclipse.hawkbit.repository.jpa.TenantMetaDataRepository;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.utils.RepositoryDataGenerator.DatabaseCleanupUtil;
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.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
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.boot.test.SpringApplicationConfiguration;
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.data.mongodb.gridfs.GridFsOperations;
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.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext;
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@SpringApplicationConfiguration(classes = { RepositoryApplicationConfiguration.class, TestConfiguration.class })
@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);
@PersistenceContext
protected EntityManager entityManager;
@Autowired
protected TargetRepository targetRepository;
@Autowired
protected ActionRepository actionRepository;
@Autowired
protected DistributionSetRepository distributionSetRepository;
@Autowired
protected SoftwareModuleRepository softwareModuleRepository;
@Autowired
protected TenantMetaDataRepository tenantMetaDataRepository;
@Autowired
protected DistributionSetTypeRepository distributionSetTypeRepository;
@Autowired
protected SoftwareModuleTypeRepository softwareModuleTypeRepository;
@Autowired
protected TargetTagRepository targetTagRepository;
@Autowired
protected DistributionSetTagRepository distributionSetTagRepository;
@Autowired
protected SoftwareModuleMetadataRepository softwareModuleMetadataRepository;
@Autowired
protected ActionStatusRepository actionStatusRepository;
@Autowired
protected ExternalArtifactRepository externalArtifactRepository;
@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 LocalArtifactRepository artifactRepository;
@Autowired
protected TargetInfoRepository targetInfoRepository;
@Autowired
protected GridFsOperations operations;
@Autowired
protected WebApplicationContext context;
@Autowired
protected ControllerManagement controllerManagament;
@Autowired
protected AuditingHandler auditingHandler;
@Autowired
protected TenantAware tenantAware;
@Autowired
protected SystemManagement systemManagement;
@Autowired
protected TenantAwareCacheManager cacheManager;
@Autowired
protected TenantConfigurationManagement tenantConfigurationManagement;
@Autowired
protected RolloutManagement rolloutManagement;
@Autowired
protected RolloutGroupManagement rolloutGroupManagement;
@Autowired
protected RolloutGroupRepository rolloutGroupRepository;
@Autowired
protected RolloutRepository rolloutRepository;
@Autowired
protected SystemSecurityContext systemSecurityContext;
protected MockMvc mvc;
@Autowired
protected DatabaseCleanupUtil dbCleanupUtil;
protected SoftwareModuleType osType;
protected SoftwareModuleType appType;
protected SoftwareModuleType runtimeType;
protected DistributionSetType standardDsType;
@Rule
public final WithSpringAuthorityRule securityRule = new WithSpringAuthorityRule();
protected Environment environment = null;
private static CIMySqlTestDatabase tesdatabase;
@Override
public void setEnvironment(final Environment environment) {
this.environment = environment;
}
@Before
public void before() throws Exception {
mvc = createMvcWebAppContext().build();
standardDsType = securityRule.runAsPrivileged(() -> systemManagement.getTenantMetadata().getDefaultDsType());
osType = securityRule.runAsPrivileged(() -> softwareManagement.findSoftwareModuleTypeByKey("os"));
osType.setDescription("Updated description to have lastmodified available in tests");
osType = securityRule.runAsPrivileged(() -> softwareManagement.updateSoftwareModuleType(osType));
appType = securityRule.runAsPrivileged(() -> softwareManagement.findSoftwareModuleTypeByKey("application"));
appType.setDescription("Updated description to have lastmodified available in tests");
appType = securityRule.runAsPrivileged(() -> softwareManagement.updateSoftwareModuleType(appType));
runtimeType = securityRule.runAsPrivileged(() -> softwareManagement.findSoftwareModuleTypeByKey("runtime"));
runtimeType.setDescription("Updated description to have lastmodified available in tests");
runtimeType = securityRule.runAsPrivileged(() -> softwareManagement.updateSoftwareModuleType(runtimeType));
}
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/**"));
}
@BeforeClass
public static void beforeClass() {
createTestdatabaseAndStart();
}
private static void createTestdatabaseAndStart() {
if ("MYSQL".equals(System.getProperty("spring.jpa.database"))) {
tesdatabase = new CIMySqlTestDatabase();
tesdatabase.before();
}
}
@AfterClass
public static void afterClass() {
if (tesdatabase != null) {
tesdatabase.after();
}
}
@After
public void after() throws Exception {
deleteAllRepos();
cacheManager.getDirectCacheNames().forEach(name -> cacheManager.getDirectCache(name).clear());
assertThat(actionStatusRepository.findAll()).isEmpty();
assertThat(targetRepository.findAll()).isEmpty();
assertThat(actionRepository.findAll()).isEmpty();
assertThat(distributionSetRepository.findAll()).isEmpty();
assertThat(targetTagRepository.findAll()).isEmpty();
assertThat(distributionSetTagRepository.findAll()).isEmpty();
assertThat(softwareModuleRepository.findAll()).isEmpty();
assertThat(softwareModuleTypeRepository.findAll()).isEmpty();
assertThat(distributionSetTypeRepository.findAll()).isEmpty();
assertThat(tenantMetaDataRepository.findAll()).isEmpty();
assertThat(rolloutGroupRepository.findAll()).isEmpty();
assertThat(rolloutRepository.findAll()).isEmpty();
}
@Transactional
protected void deleteAllRepos() throws Exception {
final List<String> tenants = securityRule.runAs(WithSpringAuthorityRule.withUser(false),
() -> systemManagement.findTenants());
tenants.forEach(tenant -> {
try {
securityRule.runAs(WithSpringAuthorityRule.withUser(false), () -> {
systemManagement.deleteTenant(tenant);
return null;
});
} catch (final Exception e) {
e.printStackTrace();
}
});
}
@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,104 @@
/**
* 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;
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.data.mongodb.core.query.Query;
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;
@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 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,90 @@
/**
* 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;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*
*/
public class CIMySqlTestDatabase implements Testdatabase {
private final static Logger LOG = LoggerFactory.getLogger(CIMySqlTestDatabase.class);
private String schemaName;
private String uri;
private final String username;
private final String password;
public CIMySqlTestDatabase() {
this.username = System.getProperty("spring.datasource.username");
this.password = System.getProperty("spring.datasource.password");
this.uri = System.getProperty("spring.datasource.url");
createSchemaUri();
initSystemProperties();
}
private final void initSystemProperties() {
System.setProperty("spring.datasource.driverClassName", getDriverClassName());
System.setProperty("spring.jpa.database", "MYSQL");
}
private void createSchemaUri() {
schemaName = "SP" + RandomStringUtils.randomAlphanumeric(10);
this.uri = this.uri.substring(0, uri.lastIndexOf("/") + 1);
System.setProperty("spring.datasource.url", uri + schemaName);
}
@Override
public void before() {
createSchema();
}
private void createSchema() {
try (Connection connection = DriverManager.getConnection(uri, username, password)) {
connection.prepareStatement("CREATE SCHEMA " + schemaName + ";").execute();
LOG.info("Schema {} created on uri {}", schemaName, uri);
} catch (final SQLException e) {
e.printStackTrace();
}
}
@Override
public void after() {
dropSchema();
}
private void dropSchema() {
try (Connection connection = DriverManager.getConnection(uri, username, password)) {
connection.prepareStatement("DROP SCHEMA " + schemaName + ";").execute();
LOG.info("Schema {} dropped on uri {}", schemaName, uri);
} catch (final SQLException e) {
e.printStackTrace();
}
}
@Override
public String getDriverClassName() {
return "org.mariadb.jdbc.Driver";
}
@Override
public String getUri() {
return uri;
}
}

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;
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,85 @@
/**
* 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;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Hash utility calls copied from
* http://www.codejava.net/coding/how-to-calculate-md5-and-sha-hash-values-in-
* java.
*
*
*
*/
public final class HashGeneratorUtils {
private static final Logger LOG = LoggerFactory.getLogger(HashGeneratorUtils.class);
private HashGeneratorUtils() {
}
/**
* Generates a MD5 cryptographic string.
*
* @param message
* the plain message
* @return the cryptographic string
*/
public static String generateMD5(final byte[] message) {
return hashString(message, "MD5");
}
/**
* Generates a SHA-1 cryptographic string.
*
* @param message
* the plain message
* @return the cryptographic string
*/
public static String generateSHA1(final byte[] message) {
return hashString(message, "SHA-1");
}
/**
* Generates a SHA-256 cryptographic string.
*
* @param message
* the plain message
* @return the cryptographic string
*/
public static String generateSHA256(final byte[] message) {
return hashString(message, "SHA-256");
}
private static String hashString(final byte[] message, final String algorithm) {
try {
final MessageDigest digest = MessageDigest.getInstance(algorithm);
final byte[] hashedBytes = digest.digest(message);
return convertByteArrayToHexString(hashedBytes);
} catch (final NoSuchAlgorithmException e) {
LOG.error("Algorithm could not be find", e);
}
return null;
}
private static String convertByteArrayToHexString(final byte[] arrayBytes) {
final StringBuilder builder = new StringBuilder();
for (int i = 0; i < arrayBytes.length; i++) {
builder.append(Integer.toString((arrayBytes[i] & 0xff) + 0x100, 16).substring(1));
}
return builder.toString();
}
}

View File

@@ -0,0 +1,118 @@
/**
* 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;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.UUID;
import org.h2.tools.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*
*/
public class LocalH2TestDatabase implements Testdatabase {
private final static Logger LOG = LoggerFactory.getLogger(LocalH2TestDatabase.class);
private final int port;
private Server h2server;
private boolean dbStarted;
private String uri;
public LocalH2TestDatabase(final int port) {
super();
this.port = port;
createUri();
initSystemProperties();
}
private final void initSystemProperties() {
System.setProperty("spring.datasource.driverClassName", getDriverClassName());
System.setProperty("spring.datasource.username", "");
System.setProperty("spring.datasource.password", "");
System.setProperty("hawkbit.server.database", "H2");
}
private void dropAllObjects() {
try (Connection connection = DriverManager.getConnection(uri)) {
connection.prepareCall("DROP ALL OBJECTS;").execute();
} catch (final SQLException e) {
e.printStackTrace();
}
}
@Override
public void before() {
try {
startDatabase();
} catch (ClassNotFoundException | SQLException | IOException e) {
e.printStackTrace();
}
}
@Override
public void after() {
try {
stopDatabase();
} catch (ClassNotFoundException | SQLException | IOException e) {
e.printStackTrace();
}
}
private void startDatabase() throws SQLException, ClassNotFoundException, IOException {
if (dbStarted) {
return;
}
// Start H2 database for OpenFire
h2server = Server
.createTcpServer(
new String[] { "-tcpPort", String.valueOf(port), "-tcpAllowOthers", "-tcpShutdownForce" })
.start();
dbStarted = true;
LOG.info("H2 Database started on port {} and uri {}", port, uri);
dropAllObjects();
}
private final void createUri() {
this.uri = "jdbc:h2:tcp://localhost:" + port + "/mem:SP" + UUID.randomUUID().toString() + ";MVCC=TRUE;"
+ "DB_CLOSE_DELAY=-1";
System.setProperty("spring.datasource.url", uri);
}
private void stopDatabase() throws SQLException, ClassNotFoundException, IOException {
if (!dbStarted) {
return;
}
h2server.stop();
h2server = null;
dbStarted = false;
try {
Thread.sleep(1000);
} catch (final InterruptedException e) {
}
}
@Override
public String getDriverClassName() {
return "org.h2.Driver";
}
@Override
public String getUri() {
return uri;
}
}

View File

@@ -0,0 +1,63 @@
/**
* 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;
import static org.fest.assertions.Assertions.assertThat;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Set;
import org.springframework.security.access.prepost.PreAuthorize;
public class MethodSecurityUtil {
private static final Set<String> METHOD_SECURITY_EXCLUSION = new HashSet<>();
static {
METHOD_SECURITY_EXCLUSION.add("equals");
METHOD_SECURITY_EXCLUSION.add("toString");
METHOD_SECURITY_EXCLUSION.add("hashCode");
METHOD_SECURITY_EXCLUSION.add("clone");
METHOD_SECURITY_EXCLUSION.add("setEnvironment");
// this method shouldn't be public on the DeploymentManagemeht but it is
METHOD_SECURITY_EXCLUSION.add("setOverrideObsoleteUpdateActions");
METHOD_SECURITY_EXCLUSION.add("isOverrideObsoleteUpdateActions");
// this method must be public accessible without security because it's
// necessary to acccess
// the security-token of a target without being authenticated because
// the security-token is
// the authentication process
// ControllerManagement#getSecurityTokenByControllerId()
METHOD_SECURITY_EXCLUSION.add("getSecurityTokenByControllerId");
}
/**
* asserts that the given methods are annotated with the
* {@link PreAuthorize} annotation for security. Inherited methods are not
* checked. The following methods are excluded due inherited from
* {@link Object}, like equals() or toString().
*
* @param clazz
* the class to retrieve the public declared methods
*/
public static void assertDeclaredMethodsContainsPreAuthorizeAnnotaions(final Class<?> clazz) {
final Method[] declaredMethods = clazz.getDeclaredMethods();
for (final Method method : declaredMethods) {
if (!METHOD_SECURITY_EXCLUSION.contains(method.getName()) && !method.isSynthetic()
&& Modifier.isPublic(method.getModifiers())) {
final PreAuthorize annotation = method.getAnnotation(PreAuthorize.class);
assertThat(annotation).as(
"The public method " + method.getName() + " is not annoated with @PreAuthorize, security leak?")
.isNotNull();
}
}
}
}

View File

@@ -0,0 +1,52 @@
/**
* 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;
import java.io.IOException;
import java.io.InputStream;
import java.security.SecureRandom;
import java.util.Random;
/**
*
*
*
*/
public class RandomGeneratedInputStream extends InputStream {
private final Random random = new SecureRandom();
/** Target size of the stream. */
private final long size;
/** Internal counter. */
private long index;
/**
* @param size
* target size of the stream [byte]
*/
public RandomGeneratedInputStream(final long size) {
super();
this.size = size;
}
@Override
public int read() throws IOException {
if (index == size) {
return -1;
}
index++;
return random.nextInt(255);
}
}

View File

@@ -0,0 +1,121 @@
/**
* 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;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.eclipse.hawkbit.cache.CacheConstants;
import org.eclipse.hawkbit.cache.TenancyCacheManager;
import org.eclipse.hawkbit.cache.TenantAwareCacheManager;
import org.eclipse.hawkbit.repository.model.helper.EventBusHolder;
import org.eclipse.hawkbit.repository.utils.RepositoryDataGenerator;
import org.eclipse.hawkbit.repository.utils.RepositoryDataGenerator.DatabaseCleanupUtil;
import org.eclipse.hawkbit.security.DdiSecurityProperties;
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
import org.eclipse.hawkbit.security.SpringSecurityAuditorAware;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.Cache;
import org.springframework.cache.guava.GuavaCacheManager;
import org.springframework.context.annotation.AdviceMode;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.domain.AuditorAware;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.security.concurrent.DelegatingSecurityContextExecutor;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.EventBus;
import com.mongodb.MongoClientOptions;
/**
* Spring context configuration required for Dev.Environment.
*
*
*
*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ, proxyTargetClass = true, securedEnabled = true)
@EnableConfigurationProperties({ HawkbitServerProperties.class, DdiSecurityProperties.class })
@Profile("test")
public class TestConfiguration implements AsyncConfigurer {
/**
* DB cleanup utility bean is created.
*
* @return the {@link DatabaseCleanupUtil} bean
*/
@Bean
public DatabaseCleanupUtil createDatabaseCleanupUtil() {
return new RepositoryDataGenerator.DatabaseCleanupUtil();
}
@Bean
public MongoClientOptions options() {
return MongoClientOptions.builder().connectTimeout(500).maxWaitTime(500).connectionsPerHost(2)
.serverSelectionTimeout(500).build();
}
@Bean
public TenantAware tenantAware() {
return new SecurityContextTenantAware();
}
@Bean
public TenancyCacheManager cacheManager() {
return new TenantAwareCacheManager(new GuavaCacheManager(), tenantAware());
}
/**
* Bean for the download id cache.
*
* @return the cache
*/
@Bean(name = CacheConstants.DOWNLOAD_ID_CACHE)
public Cache downloadIdCache() {
return cacheManager().getDirectCache(CacheConstants.DOWNLOAD_ID_CACHE);
}
@Bean
public EventBus eventBus() {
return new AsyncEventBus(asyncExecutor());
}
@Bean
public EventBusHolder eventBusHolder() {
return EventBusHolder.getInstance();
}
@Bean
public Executor asyncExecutor() {
return new DelegatingSecurityContextExecutor(Executors.newSingleThreadExecutor());
}
@Bean
public AuditorAware<String> auditorAware() {
return new SpringSecurityAuditorAware();
}
@Override
public Executor getAsyncExecutor() {
return asyncExecutor();
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SimpleAsyncUncaughtExceptionHandler();
}
}

View File

@@ -0,0 +1,436 @@
/**
* 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;
import static org.fest.assertions.api.Assertions.assertThat;
import java.io.InputStream;
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.DistributionSetManagement;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.jpa.ActionRepository;
import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaArtifact;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
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.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
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.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import net._01001111.text.LoremIpsum;
/**
* Data generator utility for tests.
*
*
*
*/
public class TestDataUtil {
private static final LoremIpsum LOREM = new LoremIpsum();
public static DistributionSet createTestDistributionSet(final SoftwareManagement softwareManagement,
final DistributionSetManagement distributionSetManagement) {
final Pageable pageReq = new PageRequest(0, 400);
DistributionSet set = TestDataUtil.generateDistributionSet("one", softwareManagement,
distributionSetManagement);
set.setVersion("anotherVersion");
set = distributionSetManagement.updateDistributionSet(set);
set.getModules().forEach(module -> {
module.setDescription("updated description");
softwareManagement.updateSoftwareModule(module);
});
// load also lazy stuff
set = distributionSetManagement.findDistributionSetByIdWithDetails(set.getId());
assertThat(distributionSetManagement.findDistributionSetsByDeletedAndOrCompleted(pageReq, false, true)).hasSize(1);
return set;
}
public static List<Target> sendUpdateActionStatusToTargets(final ControllerManagement controllerManagament,
final TargetManagement targetManagement, final ActionRepository actionRepository, final DistributionSet dsA,
final Iterable<Target> targs, final Status status, final String... msgs) {
final List<Target> result = new ArrayList<>();
for (final Target t : targs) {
final List<Action> findByTarget = actionRepository.findByTarget((JpaTarget) t);
for (final Action action : findByTarget) {
result.add(sendUpdateActionStatusToTarget(controllerManagament, targetManagement, status, action, t,
msgs));
}
}
return result;
}
private static Target sendUpdateActionStatusToTarget(final ControllerManagement controllerManagament,
final TargetManagement targetManagement, final Status status, final Action updActA, final Target t,
final String... msgs) {
updActA.setStatus(status);
final ActionStatus statusMessages = new JpaActionStatus();
statusMessages.setAction(updActA);
statusMessages.setOccurredAt(System.currentTimeMillis());
statusMessages.setStatus(status);
for (final String msg : msgs) {
statusMessages.addMessage(msg);
}
controllerManagament.addUpdateActionStatus(statusMessages);
return targetManagement.findTargetByControllerID(t.getControllerId());
}
public static List<JpaDistributionSet> generateDistributionSets(final String suffix, final int number,
final SoftwareManagement softwareManagement, final DistributionSetManagement distributionSetManagement) {
final List<JpaDistributionSet> sets = new ArrayList<>();
for (int i = 0; i < number; i++) {
sets.add(generateDistributionSet(suffix, "v1." + i, softwareManagement, distributionSetManagement, false));
}
return sets;
}
public static DistributionSet generateDistributionSetWithNoSoftwareModules(final String name, final String version,
final DistributionSetManagement distributionSetManagement) {
final DistributionSet dis = new JpaDistributionSet();
dis.setName(name);
dis.setVersion(version);
dis.setDescription("Test describtion for " + name);
return distributionSetManagement.createDistributionSet(dis);
}
public static List<JpaDistributionSet> generateDistributionSets(final int number,
final SoftwareManagement softwareManagement, final DistributionSetManagement distributionSetManagement) {
return generateDistributionSets("", number, softwareManagement, distributionSetManagement);
}
public static JpaDistributionSet generateDistributionSet(final String suffix, final String version,
final SoftwareManagement softwareManagement, final DistributionSetManagement distributionSetManagement,
final boolean isRequiredMigrationStep) {
final SoftwareModule ah = softwareManagement.createSoftwareModule(new JpaSoftwareModule(
findOrCreateSoftwareModuleType(softwareManagement, "application"), suffix + "application",
version + "." + new Random().nextInt(100), LOREM.words(20), suffix + " vendor Limited, California"));
final SoftwareModule jvm = softwareManagement.createSoftwareModule(
new JpaSoftwareModule(findOrCreateSoftwareModuleType(softwareManagement, "runtime"),
suffix + "app runtime", version + "." + new Random().nextInt(100), LOREM.words(20),
suffix + " vendor GmbH, Stuttgart, Germany"));
final SoftwareModule os = softwareManagement
.createSoftwareModule(new JpaSoftwareModule(findOrCreateSoftwareModuleType(softwareManagement, "os"),
suffix + " Firmware", version + "." + new Random().nextInt(100), LOREM.words(20),
suffix + " vendor Limited Inc, California"));
final List<SoftwareModuleType> mand = new ArrayList<>();
mand.add(findOrCreateSoftwareModuleType(softwareManagement, "os"));
final List<SoftwareModuleType> opt = new ArrayList<>();
opt.add(findOrCreateSoftwareModuleType(softwareManagement, "application"));
opt.add(findOrCreateSoftwareModuleType(softwareManagement, "runtime"));
return (JpaDistributionSet) distributionSetManagement.createDistributionSet(
buildDistributionSet(suffix != null && suffix.length() > 0 ? suffix : "DS", version,
findOrCreateDistributionSetType(distributionSetManagement, "ecl_os_app_jvm",
"OS mandatory App/JVM optional", mand, opt),
os, jvm, ah).setRequiredMigrationStep(isRequiredMigrationStep));
}
public static DistributionSet generateDistributionSet(final String suffix, final String version,
final SoftwareManagement softwareManagement, final DistributionSetManagement distributionSetManagement,
final Collection<DistributionSetTag> tags) {
final DistributionSet set = generateDistributionSet(suffix, version, softwareManagement,
distributionSetManagement, false);
final List<DistributionSet> sets = new ArrayList<DistributionSet>();
sets.add(set);
tags.forEach(tag -> distributionSetManagement.toggleTagAssignment(sets, tag));
return distributionSetManagement.findDistributionSetById(set.getId());
}
public static List<Target> generateTargets(final int number) {
return generateTargets(0, number, "Test target ");
}
public static List<Target> generateTargets(final int number, final String prefix) {
return generateTargets(0, number, prefix);
}
public static List<Target> generateTargets(final int start, final int number, final String prefix) {
final List<Target> targets = new ArrayList<>();
for (int i = start; i < start + number; i++) {
targets.add(new JpaTarget(prefix + i));
}
return targets;
}
public static List<TargetTag> generateTargetTags(final int number) {
final List<TargetTag> result = new ArrayList<>();
for (int i = 0; i < number; i++) {
result.add(new JpaTargetTag("tag" + i, "tagdesc" + i, "" + i));
}
return result;
}
public static List<DistributionSetTag> generateDistributionSetTags(final int number) {
final List<DistributionSetTag> result = new ArrayList<>();
for (int i = 0; i < number; i++) {
result.add(new JpaDistributionSetTag("tag" + i, "tagdesc" + i, "" + i));
}
return result;
}
public static JpaDistributionSet generateDistributionSet(final String suffix,
final SoftwareManagement softwareManagement, final DistributionSetManagement distributionSetManagement,
final boolean isRequiredMigrationStep) {
return generateDistributionSet(suffix, "v1.0", softwareManagement, distributionSetManagement,
isRequiredMigrationStep);
}
public static JpaDistributionSet generateDistributionSet(final String suffix,
final SoftwareManagement softwareManagement, final DistributionSetManagement distributionSetManagement) {
return generateDistributionSet(suffix, "v1.0", softwareManagement, distributionSetManagement, false);
}
public static List<AbstractJpaArtifact> generateArtifacts(final ArtifactManagement artifactManagement,
final Long moduleId) {
final List<AbstractJpaArtifact> artifacts = new ArrayList<>();
for (int i = 0; i < 3; i++) {
final InputStream stubInputStream = IOUtils.toInputStream("some test data" + i);
artifacts.add((AbstractJpaArtifact) artifactManagement.createLocalArtifact(stubInputStream, moduleId,
"filename" + i, false));
}
return artifacts;
}
public static Target createTarget(final TargetManagement targetManagement) {
final String targetExist = "targetExist";
final Target target = new JpaTarget(targetExist);
targetManagement.createTarget(target);
return target;
}
public static DistributionSet generateDistributionSet(final String suffix,
final SoftwareManagement softwareManagement, final DistributionSetManagement distributionSetManagement,
final Collection<DistributionSetTag> tags) {
return generateDistributionSet(suffix, "v1.0", softwareManagement, distributionSetManagement, tags);
}
public static SoftwareModuleType findOrCreateSoftwareModuleType(final SoftwareManagement softwareManagement,
final String softwareModuleType) {
final SoftwareModuleType findSoftwareModuleTypeByKey = softwareManagement
.findSoftwareModuleTypeByKey(softwareModuleType);
if (findSoftwareModuleTypeByKey != null) {
return findSoftwareModuleTypeByKey;
}
return softwareManagement.createSoftwareModuleType(new JpaSoftwareModuleType(softwareModuleType,
softwareModuleType, "Standard type " + softwareManagement, 1));
}
public static DistributionSetType findOrCreateDistributionSetType(
final DistributionSetManagement distributionSetManagement, 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 = new JpaDistributionSetType(dsTypeKey, dsTypeName,
"Standard type" + dsTypeName);
mandatory.forEach(entry -> type.addMandatoryModuleType(entry));
optional.forEach(entry -> type.addOptionalModuleType(entry));
return distributionSetManagement.createDistributionSetType(type);
}
/**
* builds a set of {@link Target} fixtures from the given parameters.
*
* @param noOfTgts
* number of targets to create
* @param ctlrIDPrefix
* prefix used for the controller ID
* @param descriptionPrefix
* prefix used for the description
* @return set of {@link Target}
*/
public static List<Target> buildTargetFixtures(final int noOfTgts, final String ctlrIDPrefix,
final String descriptionPrefix) {
return buildTargetFixtures(noOfTgts, ctlrIDPrefix, 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 ctlrIDPrefix
* prefix of the controllerID which is concatenated with the
* number of the target
* @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
*/
public static List<Target> buildTargetFixtures(final int noOfTgts, final String ctlrIDPrefix,
final String descriptionPrefix, final TargetTag[] tags) {
final List<Target> list = new ArrayList<Target>();
for (int i = 0; i < noOfTgts; i++) {
String ctrlID = ctlrIDPrefix;
if (Strings.isNullOrEmpty(ctrlID)) {
ctrlID = UUID.randomUUID().toString();
}
ctrlID = String.format("%s-%05d", ctrlID, i);
final String description = String.format("the description of ProvisioningTarget: [%s]", ctrlID);
final Target target = buildTargetFixture(ctrlID, description, tags);
list.add(target);
}
return list;
}
/**
* builds a single {@link Target} fixture from the given parameters.
*
* @param ctrlID
* controllerID
* @param description
* the description of the target
* @param tags
* assigned {@link TargetTag}s
* @return the created {@link Target}
*/
public static Target buildTargetFixture(final String ctrlID, final String description, final TargetTag[] tags) {
final Target target = new JpaTarget(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;
}
/**
* 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 static Target buildTargetFixture(final String ctrlID, final String description) {
return buildTargetFixture(ctrlID, description, null);
}
/**
* builder method for creating a {@link DistributionSet}.
*
* @param name
* of the DS
* @param version
* of the DS
* @param os
* operating system of the DS
* @param jvm
* java virtual machine of the DS
* @param agentHub
* of the DS
* @return the created {@link DistributionSet}
*/
public static DistributionSet buildDistributionSet(final String name, final String version,
final DistributionSetType type, final SoftwareModule os, final SoftwareModule jvm,
final SoftwareModule agentHub) {
final DistributionSet distributionSet = new JpaDistributionSet(name, version, null, type,
Lists.newArrayList(os, jvm, agentHub));
distributionSet.setDescription(
String.format("description of DistributionSet; name = '%s', version = '%s'", name, version));
return distributionSet;
}
/**
* builder method for creating a set of {@link TargetTag}.
*
* @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 static List<TargetTag> buildTargetTagFixtures(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 = buildTargetTagFixture(tagName);
list.add(targetTag);
}
return list;
}
/**
* builder method for creating a simple {@link TargetTag}.
*
* @param tagName
* name of the Tag
* @return the {@link TargetTag}
*/
public static TargetTag buildTargetTagFixture(final String tagName) {
return new JpaTargetTag(tagName);
}
}

View File

@@ -0,0 +1,25 @@
/**
* 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;
/**
*
*
*/
public interface Testdatabase {
void before();
void after();
public String getUri();
String getDriverClassName();
}

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

View File

@@ -0,0 +1,29 @@
/**
* 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.cache;
import static org.fest.assertions.api.Assertions.assertThat;
import org.junit.Test;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Unit Tests - Repository")
@Stories("CacheKeys")
public class CacheKeysTest {
@Test
public void entitySpecificCacheKeyPattern() {
final String knownEntityId = "123";
final String knownCacheKey = "someField";
final String entitySpecificCacheKey = CacheKeys.entitySpecificCacheKey(knownEntityId, knownCacheKey);
assertThat(entitySpecificCacheKey).isEqualTo(knownEntityId + "." + knownCacheKey);
}
}

View File

@@ -0,0 +1,74 @@
/**
* 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.cache;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import com.google.common.eventbus.EventBus;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Unit Tests - Repository")
@Stories("CacheWriteNotify")
@RunWith(MockitoJUnitRunner.class)
public class CacheWriteNotifyTest {
@Mock
private EventBus eventBusMock;
@Mock
private CacheManager cacheManagerMock;
@Mock
private Cache cacheMock;
@Mock
private TenantAware tenantAwareMock;
private CacheWriteNotify underTest;
@Before
public void before() {
underTest = new CacheWriteNotify();
underTest.setEventBus(eventBusMock);
underTest.setCacheManager(cacheManagerMock);
underTest.setTenantAware(tenantAwareMock);
}
@Test
public void downloadgProgressIsCachedAndEventSent() {
final long knownStatusId = 1;
final int knownPercentage = 23;
when(cacheManagerMock.getCache(Action.class.getName())).thenReturn(cacheMock);
when(tenantAwareMock.getCurrentTenant()).thenReturn("default");
underTest.downloadProgressPercent(knownStatusId, knownPercentage);
verify(cacheManagerMock).getCache(eq(Action.class.getName()));
verify(cacheMock).put(knownStatusId + "." + CacheKeys.DOWNLOAD_PROGRESS_PERCENT, knownPercentage);
verify(eventBusMock).post(any(DownloadProgressEvent.class));
}
}

View File

@@ -0,0 +1,128 @@
/**
* 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.eventbus;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.eclipse.hawkbit.cache.CacheField;
import org.eclipse.hawkbit.cache.CacheKeys;
import org.eclipse.hawkbit.repository.model.helper.CacheManagerHolder;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.hateoas.Identifiable;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Unit Tests - Repository")
@Stories("EventBus")
@RunWith(MockitoJUnitRunner.class)
public class CacheFieldEntityListenerTest {
private static final String TEST_CACHE_FIELD = "testCacheField";
@Mock
private CacheManager cacheManagerMock;
@Mock
private Cache cacheMock;
private CacheFieldEntityListener underTest;
@Before
public void before() {
// mock
when(cacheManagerMock.getCache(anyString())).thenReturn(cacheMock);
underTest = new CacheFieldEntityListener();
CacheManagerHolder.getInstance().setCacheManager(cacheManagerMock);
}
@Test
public void postLoadSetsCacheFields() {
final String entityId = "123";
final String normalFieldValue = "bumlux";
final TestEntity testObject = new TestEntity(entityId, normalFieldValue);
final int expectedTestValue = -1;
when(cacheMock.get(CacheKeys.entitySpecificCacheKey(entityId, TEST_CACHE_FIELD)))
.thenReturn(new SimpleValueWrapper(expectedTestValue));
// pre verify everything is ok
assertThat(testObject.getCacheField()).isNotEqualTo(expectedTestValue);
assertThat(testObject.getNormalField()).isEqualTo(normalFieldValue);
// test
underTest.postLoad(testObject);
assertThat(testObject.getNormalField()).isEqualTo(normalFieldValue);
// now cache value should be like the value in the mock of the cache
assertThat(testObject.getCacheField()).isEqualTo(expectedTestValue);
}
@Test
public void postRemoveEvictsCacheField() {
final String entityId = "123";
final String normalFieldValue = "bumlux";
final TestEntity testObject = new TestEntity(entityId, normalFieldValue);
// test
underTest.postDelete(testObject);
verify(cacheMock).evict(eq(CacheKeys.entitySpecificCacheKey(entityId, TEST_CACHE_FIELD)));
}
private final class TestEntity implements Identifiable<String> {
private final String id;
private final String normalField;
@CacheField(key = TEST_CACHE_FIELD)
private int cacheField;
private TestEntity(final String id, final String normalFieldValue) {
this.id = id;
this.normalField = normalFieldValue;
}
/*
* (non-Javadoc)
*
* @see org.springframework.hateoas.Identifiable#getId()
*/
@Override
public String getId() {
return id;
}
/**
* @return the normalField
*/
String getNormalField() {
return normalField;
}
/**
* @return the cacheField
*/
int getCacheField() {
return cacheField;
}
}
}

View File

@@ -0,0 +1,42 @@
/**
* 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;
import static org.fest.assertions.api.Assertions.assertThat;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.junit.Test;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Unit Tests - Repository")
@Stories("Deployment Management")
public class ActionTest {
@Test
@Description("Ensures that timeforced moded switch from soft to forces after defined timeframe.")
public void timeforcedHitNewHasCodeIsGenerated() throws InterruptedException {
final boolean active;
// current time + 1 seconds
final long sleepTime = 1000;
final long timeForceTimeAt = System.currentTimeMillis() + sleepTime;
final JpaAction timeforcedAction = new JpaAction();
timeforcedAction.setActionType(ActionType.TIMEFORCED);
timeforcedAction.setForcedTime(timeForceTimeAt);
assertThat(timeforcedAction.isForce()).isFalse();
// wait until timeforce time is hit
Thread.sleep(sleepTime + 100);
assertThat(timeforcedAction.isForce()).isTrue();
}
}

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
*/
package org.eclipse.hawkbit.repository;
import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import org.apache.commons.lang3.RandomStringUtils;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.repository.exception.ArtifactUploadFailedException;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.junit.BeforeClass;
import org.junit.Test;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
/**
* Addition tests next to {@link ArtifactManagementTest} with no running MongoDB
*
*/
@Features("Component Tests - Repository")
@Stories("Artifact Management")
public class ArtifactManagementNoMongoDbTest extends AbstractIntegrationTest {
@BeforeClass
public static void initialize() {
// set property to mongoPort which does not start any mongoDB of
// parallel test execution
System.setProperty("spring.data.mongodb.port", "1020");
}
@Test
@Description("Checks if the expected ArtifactUploadFailedException is thrown in case of MongoDB down")
public void createLocalArtifactWithMongoDbDown() throws IOException {
JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1",
"version 1", null, null);
sm = softwareModuleRepository.save(sm);
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
try {
artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm.getId(), "file1", false);
fail("Should not have worked with MongoDb down.");
} catch (final ArtifactUploadFailedException e) {
}
}
}

View File

@@ -0,0 +1,401 @@
/**
* 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;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.UnknownHostException;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB;
import org.eclipse.hawkbit.HashGeneratorUtils;
import org.eclipse.hawkbit.RandomGeneratedInputStream;
import org.eclipse.hawkbit.WithUser;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.repository.exception.ArtifactDeleteFailedException;
import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException;
import org.eclipse.hawkbit.repository.jpa.model.JpaExternalArtifact;
import org.eclipse.hawkbit.repository.jpa.model.JpaExternalArtifactProvider;
import org.eclipse.hawkbit.repository.jpa.model.JpaLocalArtifact;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.ExternalArtifactProvider;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.junit.Test;
import org.slf4j.LoggerFactory;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
/**
* Test class for {@link ArtifactManagement} with running MongoDB instance..
*
*
*
*
*/
@Features("Component Tests - Repository")
@Stories("Artifact Management")
public class ArtifactManagementTest extends AbstractIntegrationTestWithMongoDB {
public ArtifactManagementTest() {
LOG = LoggerFactory.getLogger(ArtifactManagementTest.class);
}
/**
* Test method for
* {@link org.eclipse.hawkbit.repository.ArtifactManagement#createLocalArtifact(java.io.InputStream)}
* .
*
* @throws IOException
* @throws NoSuchAlgorithmException
*/
@Test
@Description("Test if a local artifact can be created by API including metadata.")
public void createLocalArtifact() throws NoSuchAlgorithmException, IOException {
// checkbaseline
assertThat(softwareModuleRepository.findAll()).hasSize(0);
assertThat(artifactRepository.findAll()).hasSize(0);
JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1",
"version 1", null, null);
sm = softwareModuleRepository.save(sm);
JpaSoftwareModule sm2 = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 2",
"version 2", null, null);
sm2 = softwareModuleRepository.save(sm2);
JpaSoftwareModule sm3 = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 3",
"version 3", null, null);
sm3 = softwareModuleRepository.save(sm3);
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
final Artifact result = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm.getId(),
"file1", false);
final Artifact result11 = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm.getId(),
"file11", false);
final Artifact result12 = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm.getId(),
"file12", false);
final Artifact result2 = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm2.getId(),
"file2", false);
assertThat(result).isInstanceOf(LocalArtifact.class);
assertThat(result.getSoftwareModule().getId()).isEqualTo(sm.getId());
assertThat(result2.getSoftwareModule().getId()).isEqualTo(sm2.getId());
assertThat(((JpaLocalArtifact) result).getFilename()).isEqualTo("file1");
assertThat(((JpaLocalArtifact) result).getGridFsFileName()).isNotNull();
assertThat(result).isNotEqualTo(result2);
assertThat(((JpaLocalArtifact) result).getGridFsFileName())
.isEqualTo(((JpaLocalArtifact) result2).getGridFsFileName());
assertThat(artifactManagement.findLocalArtifactByFilename("file1").get(0).getSha1Hash())
.isEqualTo(HashGeneratorUtils.generateSHA1(random));
assertThat(artifactManagement.findLocalArtifactByFilename("file1").get(0).getMd5Hash())
.isEqualTo(HashGeneratorUtils.generateMD5(random));
assertThat(artifactRepository.findAll()).hasSize(4);
assertThat(softwareModuleRepository.findAll()).hasSize(3);
assertThat(softwareManagement.findSoftwareModuleWithDetails(sm.getId()).getArtifacts()).hasSize(3);
}
@Test
@Description("Tests hard delete directly on repository.")
public void hardDeleteSoftwareModule() throws NoSuchAlgorithmException, IOException {
JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1",
"version 1", null, null);
sm = softwareModuleRepository.save(sm);
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm.getId(), "file1", false);
assertThat(artifactRepository.findAll()).hasSize(1);
softwareModuleRepository.deleteAll();
assertThat(artifactRepository.findAll()).hasSize(0);
}
/**
* Test method for
* {@link org.eclipse.hawkbit.repository.ArtifactManagement#createExternalArtifact(org.eclipse.hawkbit.repository.model.ExternalArtifactProvider, java.lang.String)}
* .
*/
@Test
@Description("Tests the creation of an external artifact metadata element.")
public void createExternalArtifact() {
JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1",
"version 1", null, null);
sm = softwareModuleRepository.save(sm);
JpaSoftwareModule sm2 = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 2",
"version 2", null, null);
sm2 = softwareModuleRepository.save(sm2);
final ExternalArtifactProvider provider = artifactManagement.createExternalArtifactProvider("provider X", null,
"https://fhghdfjgh", "/{version}/");
JpaExternalArtifact result = (JpaExternalArtifact) artifactManagement.createExternalArtifact(provider, null,
sm.getId());
assertNotNull("The result of an external artifact should not be null", result);
assertThat(externalArtifactRepository.findAll()).contains(result).hasSize(1);
assertThat(result.getSoftwareModule().getId()).isEqualTo(sm.getId());
assertThat(result.getUrl()).isEqualTo("https://fhghdfjgh/{version}/");
assertThat(result.getExternalArtifactProvider()).isEqualTo(provider);
result = (JpaExternalArtifact) artifactManagement.createExternalArtifact(provider, "/test", sm2.getId());
assertNotNull("The newly created external artifact should not be null", result);
assertThat(externalArtifactRepository.findAll()).contains(result).hasSize(2);
assertThat(result.getUrl()).isEqualTo("https://fhghdfjgh/test");
assertThat(result.getExternalArtifactProvider()).isEqualTo(provider);
}
@Test
@Description("Tests deletio of an external artifact metadata element.")
public void deleteExternalArtifact() {
assertThat(artifactRepository.findAll()).isEmpty();
JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1",
"version 1", null, null);
sm = softwareModuleRepository.save(sm);
final JpaExternalArtifactProvider provider = (JpaExternalArtifactProvider) artifactManagement
.createExternalArtifactProvider("provider X", null, "https://fhghdfjgh", "/{version}/");
final JpaExternalArtifact result = (JpaExternalArtifact) artifactManagement.createExternalArtifact(provider,
null, sm.getId());
assertNotNull("The newly created external artifact should not be null", result);
assertThat(externalArtifactRepository.findAll()).contains(result).hasSize(1);
artifactManagement.deleteExternalArtifact(result.getId());
assertThat(externalArtifactRepository.findAll()).isEmpty();
}
/**
* Test method for
* {@link org.eclipse.hawkbit.repository.ArtifactManagement#deleteLocalArtifact(java.lang.Long)}
* .
*
* @throws IOException
* @throws NoSuchAlgorithmException
*/
@Test
@Description("Tests the deletion of a local artifact including metadata.")
public void deleteLocalArtifact() throws NoSuchAlgorithmException, IOException {
JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1",
"version 1", null, null);
sm = softwareModuleRepository.save(sm);
JpaSoftwareModule sm2 = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 2",
"version 2", null, null);
sm2 = softwareModuleRepository.save(sm2);
assertThat(artifactRepository.findAll()).isEmpty();
final Artifact result = artifactManagement.createLocalArtifact(new RandomGeneratedInputStream(5 * 1024),
sm.getId(), "file1", false);
final Artifact result2 = artifactManagement.createLocalArtifact(new RandomGeneratedInputStream(5 * 1024),
sm2.getId(), "file2", false);
assertThat(artifactRepository.findAll()).hasSize(2);
assertThat(result.getId()).isNotNull();
assertThat(result2.getId()).isNotNull();
assertThat(((JpaLocalArtifact) result).getGridFsFileName())
.isNotEqualTo(((JpaLocalArtifact) result2).getGridFsFileName());
assertThat(operations.findOne(new Query()
.addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result).getGridFsFileName()))))
.isNotNull();
assertThat(operations.findOne(new Query()
.addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result2).getGridFsFileName()))))
.isNotNull();
artifactManagement.deleteLocalArtifact(result.getId());
assertThat(operations.findOne(new Query()
.addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result).getGridFsFileName())))).isNull();
assertThat(operations.findOne(new Query()
.addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result2).getGridFsFileName()))))
.isNotNull();
artifactManagement.deleteLocalArtifact(result2.getId());
assertThat(operations.findOne(new Query()
.addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result2).getGridFsFileName()))))
.isNull();
assertThat(artifactRepository.findAll()).hasSize(0);
}
@Test
@Description("Trys and fails to delete local artifact with a down mongodb and checks if expected ArtifactDeleteFailedException is thrown.")
public void deleteArtifactsWithNoMongoDb() throws UnknownHostException, IOException {
// ensure baseline
assertThat(artifactRepository.findAll()).isEmpty();
// prepare test
JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1",
"version 1", null, null);
sm = softwareModuleRepository.save(sm);
final Artifact result = artifactManagement.createLocalArtifact(new RandomGeneratedInputStream(5 * 1024),
sm.getId(), "file1", false);
assertThat(artifactRepository.findAll()).hasSize(1);
internalShutDownMongo();
try {
artifactManagement.deleteLocalArtifact(result.getId());
fail("deletion should have failed");
} catch (final ArtifactDeleteFailedException e) {
}
setupMongo();
assertThat(artifactRepository.findAll()).hasSize(1);
assertThat(artifactManagement.findArtifact(result.getId())).isEqualTo(result);
}
@Test
@Description("Test the deletion of an artifact metadata where the binary is still linked to another "
+ "metadata element. The expected result is that the metadata is deleted but the binary kept.")
public void deleteDuplicateArtifacts() throws NoSuchAlgorithmException, IOException {
JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1",
"version 1", null, null);
sm = softwareModuleRepository.save(sm);
JpaSoftwareModule sm2 = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 2",
"version 2", null, null);
sm2 = softwareModuleRepository.save(sm2);
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
final Artifact result = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm.getId(),
"file1", false);
final Artifact result2 = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm2.getId(),
"file2", false);
assertThat(artifactRepository.findAll()).hasSize(2);
assertThat(result.getId()).isNotNull();
assertThat(result2.getId()).isNotNull();
assertThat(((JpaLocalArtifact) result).getGridFsFileName())
.isEqualTo(((JpaLocalArtifact) result2).getGridFsFileName());
assertThat(operations.findOne(new Query()
.addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result).getGridFsFileName()))))
.isNotNull();
artifactManagement.deleteLocalArtifact(result.getId());
assertThat(operations.findOne(new Query()
.addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result).getGridFsFileName()))))
.isNotNull();
artifactManagement.deleteLocalArtifact(result2.getId());
assertThat(operations.findOne(new Query()
.addCriteria(Criteria.where("filename").is(((JpaLocalArtifact) result).getGridFsFileName())))).isNull();
}
/**
* Test method for
* {@link org.eclipse.hawkbit.repository.ArtifactManagement#findArtifact(java.lang.Long)}
* .
*
* @throws IOException
* @throws NoSuchAlgorithmException
*/
@Test
@Description("Loads an artifact based on given ID.")
public void findArtifact() throws NoSuchAlgorithmException, IOException {
SoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1",
"version 1", null, null);
sm = softwareManagement.createSoftwareModule(sm);
final Artifact result = artifactManagement.createLocalArtifact(new RandomGeneratedInputStream(5 * 1024),
sm.getId(), "file1", false);
assertThat(artifactManagement.findArtifact(result.getId())).isEqualTo(result);
}
/**
* Test method for
* {@link org.eclipse.hawkbit.repository.ArtifactManagement#loadLocalArtifactBinary(java.lang.Long)}
* .
*
* @throws IOException
* @throws NoSuchAlgorithmException
*/
@Test
@Description("Loads an artifact binary based on given ID.")
public void loadStreamOfLocalArtifact() throws NoSuchAlgorithmException, IOException {
SoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1",
"version 1", null, null);
sm = softwareManagement.createSoftwareModule(sm);
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
final LocalArtifact result = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
sm.getId(), "file1", false);
assertTrue("The stored binary matches the given binary", IOUtils.contentEquals(new ByteArrayInputStream(random),
artifactManagement.loadLocalArtifactBinary(result).getFileInputStream()));
}
@Test
@WithUser(allSpPermissions = true, removeFromAllPermission = { SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT })
@Description("Trys and fails to load an artifact without required permission. Checks if expected InsufficientPermissionException is thrown.")
public void loadLocalArtifactBinaryWithoutDownloadArtifactThrowsPermissionDenied() {
try {
artifactManagement.loadLocalArtifactBinary(new JpaLocalArtifact());
fail("Should not have worked with missing permission.");
} catch (final InsufficientPermissionException e) {
}
}
@Test
@Description("Searches an artifact through the relations of a software module.")
public void findLocalArtifactBySoftwareModule() {
SoftwareModule sm = new JpaSoftwareModule(osType, "name 1", "version 1", null, null);
sm = softwareManagement.createSoftwareModule(sm);
SoftwareModule sm2 = new JpaSoftwareModule(osType, "name 2", "version 2", null, null);
sm2 = softwareManagement.createSoftwareModule(sm2);
assertThat(artifactManagement.findLocalArtifactBySoftwareModule(pageReq, sm.getId())).isEmpty();
final Artifact result = artifactManagement.createLocalArtifact(new RandomGeneratedInputStream(5 * 1024),
sm.getId(), "file1", false);
assertThat(artifactManagement.findLocalArtifactBySoftwareModule(pageReq, sm.getId())).hasSize(1);
}
@Test
@Description("Searches an artifact through the relations of a software module and the filename.")
public void findByFilenameAndSoftwareModule() {
SoftwareModule sm = new JpaSoftwareModule(osType, "name 1", "version 1", null, null);
sm = softwareManagement.createSoftwareModule(sm);
assertThat(artifactManagement.findByFilenameAndSoftwareModule("file1", sm.getId())).isEmpty();
artifactManagement.createLocalArtifact(new RandomGeneratedInputStream(5 * 1024), sm.getId(), "file1", false);
artifactManagement.createLocalArtifact(new RandomGeneratedInputStream(5 * 1024), sm.getId(), "file2", false);
assertThat(artifactManagement.findByFilenameAndSoftwareModule("file1", sm.getId())).hasSize(1);
}
}

View File

@@ -0,0 +1,139 @@
/**
* 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;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.List;
import javax.validation.ConstraintViolationException;
import org.apache.commons.lang3.RandomStringUtils;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.TestDataUtil;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
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.DistributionSet;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.junit.Test;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("Controller Management")
public class ControllerManagementTest extends AbstractIntegrationTest {
@Test
@Description("Controller adds a new action status.")
public void controllerAddsActionStatus() {
final Target target = new JpaTarget("4712");
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
distributionSetManagement);
Target savedTarget = targetManagement.createTarget(target);
final List<Target> toAssign = new ArrayList<>();
toAssign.add(savedTarget);
assertThat(savedTarget.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.UNKNOWN);
savedTarget = deploymentManagement.assignDistributionSet(ds, toAssign).getAssignedEntity().iterator().next();
final Action savedAction = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0);
assertThat(targetManagement.findTargetByControllerID(savedTarget.getControllerId()).getTargetInfo()
.getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING);
ActionStatus actionStatusMessage = new JpaActionStatus(savedAction, Action.Status.RUNNING,
System.currentTimeMillis());
actionStatusMessage.addMessage("foobar");
savedAction.setStatus(Status.RUNNING);
controllerManagament.addUpdateActionStatus(actionStatusMessage);
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getUpdateStatus())
.isEqualTo(TargetUpdateStatus.PENDING);
actionStatusMessage = new JpaActionStatus(savedAction, Action.Status.FINISHED, System.currentTimeMillis());
actionStatusMessage.addMessage(RandomStringUtils.randomAscii(512));
savedAction.setStatus(Status.FINISHED);
controllerManagament.addUpdateActionStatus(actionStatusMessage);
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getUpdateStatus())
.isEqualTo(TargetUpdateStatus.IN_SYNC);
assertThat(actionStatusRepository.findAll(pageReq).getNumberOfElements()).isEqualTo(3);
assertThat(deploymentManagement.findActionStatusByAction(pageReq, savedAction).getNumberOfElements())
.isEqualTo(3);
}
@Test
@Description("Register a controller which does not exist")
public void testfindOrRegisterTargetIfItDoesNotexist() {
final Target target = controllerManagament.findOrRegisterTargetIfItDoesNotexist("AA", null);
assertThat(target).as("target should not be null").isNotNull();
final Target sameTarget = controllerManagament.findOrRegisterTargetIfItDoesNotexist("AA", null);
assertThat(target).as("Target should be the equals").isEqualTo(sameTarget);
assertThat(targetRepository.count()).as("Only 1 target should be registred").isEqualTo(1L);
// throws exception
try {
controllerManagament.findOrRegisterTargetIfItDoesNotexist("", null);
fail("should fail as target does not exist");
} catch (final ConstraintViolationException e) {
}
}
@Test
@Description("Controller trys to finish an update process after it has been finished by an error action status.")
public void tryToFinishUpdateProcessMoreThenOnce() {
// mock
final Target target = new JpaTarget("Rabbit");
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
distributionSetManagement);
Target savedTarget = targetManagement.createTarget(target);
final List<Target> toAssign = new ArrayList<>();
toAssign.add(savedTarget);
savedTarget = deploymentManagement.assignDistributionSet(ds, toAssign).getAssignedEntity().iterator().next();
Action savedAction = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0);
// test and verify
final ActionStatus actionStatusMessage = new JpaActionStatus(savedAction, Action.Status.RUNNING,
System.currentTimeMillis());
actionStatusMessage.addMessage("running");
savedAction = controllerManagament.addUpdateActionStatus(actionStatusMessage);
assertThat(targetManagement.findTargetByControllerID("Rabbit").getTargetInfo().getUpdateStatus())
.isEqualTo(TargetUpdateStatus.PENDING);
final ActionStatus actionStatusMessage2 = new JpaActionStatus(savedAction, Action.Status.ERROR,
System.currentTimeMillis());
actionStatusMessage2.addMessage("error");
savedAction = controllerManagament.addUpdateActionStatus(actionStatusMessage2);
assertThat(targetManagement.findTargetByControllerID("Rabbit").getTargetInfo().getUpdateStatus())
.isEqualTo(TargetUpdateStatus.ERROR);
final ActionStatus actionStatusMessage3 = new JpaActionStatus(savedAction, Action.Status.FINISHED,
System.currentTimeMillis());
actionStatusMessage3.addMessage("finish");
controllerManagament.addUpdateActionStatus(actionStatusMessage3);
targetManagement.findTargetByControllerID("Rabbit").getTargetInfo().getUpdateStatus();
// test
assertThat(targetManagement.findTargetByControllerID("Rabbit").getTargetInfo().getUpdateStatus())
.isEqualTo(TargetUpdateStatus.ERROR);
}
}

View File

@@ -0,0 +1,841 @@
/**
* 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;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.TestDataUtil;
import org.eclipse.hawkbit.WithUser;
import org.eclipse.hawkbit.repository.DistributionSetFilter.DistributionSetFilterBuilder;
import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityLockedException;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
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.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.fest.assertions.core.Condition;
import org.junit.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import com.google.common.collect.Lists;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
/**
* {@link DistributionSetManagement} tests.
*
*/
@Features("Component Tests - Repository")
@Stories("DistributionSet Management")
public class DistributionSetManagementTest extends AbstractIntegrationTest {
@Test
@Description("Tests the successfull module update of unused distribution set type which is in fact allowed.")
public void updateUnassignedDistributionSetTypeModules() {
DistributionSetType updatableType = distributionSetManagement
.createDistributionSetType(new JpaDistributionSetType("updatableType", "to be deleted", ""));
assertThat(distributionSetManagement.findDistributionSetTypeByKey("updatableType").getMandatoryModuleTypes())
.isEmpty();
// add OS
updatableType.addMandatoryModuleType(osType);
updatableType = distributionSetManagement.updateDistributionSetType(updatableType);
assertThat(distributionSetManagement.findDistributionSetTypeByKey("updatableType").getMandatoryModuleTypes())
.containsOnly(osType);
// add JVM
updatableType.addMandatoryModuleType(runtimeType);
updatableType = distributionSetManagement.updateDistributionSetType(updatableType);
assertThat(distributionSetManagement.findDistributionSetTypeByKey("updatableType").getMandatoryModuleTypes())
.containsOnly(osType, runtimeType);
// remove OS
updatableType.removeModuleType(osType.getId());
updatableType = distributionSetManagement.updateDistributionSetType(updatableType);
assertThat(distributionSetManagement.findDistributionSetTypeByKey("updatableType").getMandatoryModuleTypes())
.containsOnly(runtimeType);
}
@Test
@Description("Tests the successfull update of used distribution set type meta data hich is in fact allowed.")
public void updateAssignedDistributionSetTypeMetaData() {
final DistributionSetType nonUpdatableType = distributionSetManagement
.createDistributionSetType(new JpaDistributionSetType("updatableType", "to be deletd", ""));
assertThat(distributionSetManagement.findDistributionSetTypeByKey("updatableType").getMandatoryModuleTypes())
.isEmpty();
distributionSetManagement
.createDistributionSet(new JpaDistributionSet("newtypesoft", "1", "", nonUpdatableType, null));
nonUpdatableType.setDescription("a new description");
nonUpdatableType.setColour("test123");
distributionSetManagement.updateDistributionSetType(nonUpdatableType);
assertThat(distributionSetManagement.findDistributionSetTypeByKey("updatableType").getDescription())
.isEqualTo("a new description");
assertThat(distributionSetManagement.findDistributionSetTypeByKey("updatableType").getColour())
.isEqualTo("test123");
}
@Test
@Description("Tests the unsuccessfull update of used distribution set type (module addition).")
public void addModuleToAssignedDistributionSetTypeFails() {
final DistributionSetType nonUpdatableType = distributionSetManagement
.createDistributionSetType(new JpaDistributionSetType("updatableType", "to be deletd", ""));
assertThat(distributionSetManagement.findDistributionSetTypeByKey("updatableType").getMandatoryModuleTypes())
.isEmpty();
distributionSetManagement
.createDistributionSet(new JpaDistributionSet("newtypesoft", "1", "", nonUpdatableType, null));
nonUpdatableType.addMandatoryModuleType(osType);
try {
distributionSetManagement.updateDistributionSetType(nonUpdatableType);
fail("Should not have worked as DS is in use.");
} catch (final EntityReadOnlyException e) {
}
}
@Test
@Description("Tests the unsuccessfull update of used distribution set type (module removal).")
public void removeModuleToAssignedDistributionSetTypeFails() {
DistributionSetType nonUpdatableType = distributionSetManagement
.createDistributionSetType(new JpaDistributionSetType("updatableType", "to be deletd", ""));
assertThat(distributionSetManagement.findDistributionSetTypeByKey("updatableType").getMandatoryModuleTypes())
.isEmpty();
nonUpdatableType.addMandatoryModuleType(osType);
nonUpdatableType = distributionSetManagement.updateDistributionSetType(nonUpdatableType);
distributionSetManagement
.createDistributionSet(new JpaDistributionSet("newtypesoft", "1", "", nonUpdatableType, null));
nonUpdatableType.removeModuleType(osType.getId());
try {
distributionSetManagement.updateDistributionSetType(nonUpdatableType);
fail("Should not have worked as DS is in use.");
} catch (final EntityReadOnlyException e) {
}
}
@Test
@Description("Tests the successfull deletion of unused (hard delete) distribution set types.")
public void deleteUnassignedDistributionSetType() {
final JpaDistributionSetType hardDelete = (JpaDistributionSetType) distributionSetManagement
.createDistributionSetType(new JpaDistributionSetType("deleted", "to be deleted", ""));
assertThat(distributionSetTypeRepository.findAll()).contains(hardDelete);
distributionSetManagement.deleteDistributionSetType(hardDelete);
assertThat(distributionSetTypeRepository.findAll()).doesNotContain(hardDelete);
}
@Test
@Description("Tests the successfull deletion of used (soft delete) distribution set types.")
public void deleteAssignedDistributionSetType() {
final JpaDistributionSetType softDelete = (JpaDistributionSetType) distributionSetManagement
.createDistributionSetType(new JpaDistributionSetType("softdeleted", "to be deletd", ""));
assertThat(distributionSetTypeRepository.findAll()).contains(softDelete);
distributionSetManagement
.createDistributionSet(new JpaDistributionSet("newtypesoft", "1", "", softDelete, null));
distributionSetManagement.deleteDistributionSetType(softDelete);
assertThat(distributionSetManagement.findDistributionSetTypeByKey("softdeleted").isDeleted()).isEqualTo(true);
}
@Test
@Description("Ensures that it is not possible to create a DS that already exists (unique constraint is on name,version for DS).")
public void createDuplicateDistributionSetsFailsWithException() {
TestDataUtil.generateDistributionSet("a", softwareManagement, distributionSetManagement);
try {
TestDataUtil.generateDistributionSet("a", softwareManagement, distributionSetManagement);
fail("Should not have worked as DS with same UK already exists.");
} catch (final EntityAlreadyExistsException e) {
}
}
@Test
@Description("Verfies that a DS is of default type if not specified explicitly at creation time.")
public void createDistributionSetWithImplicitType() {
final DistributionSet set = distributionSetManagement
.createDistributionSet(new JpaDistributionSet("newtypesoft", "1", "", null, null));
assertThat(set.getType()).as("Type should be equal to default type of tenant")
.isEqualTo(systemManagement.getTenantMetadata().getDefaultDsType());
}
@Test
@Description("Verfies that multiple DS are of default type if not specified explicitly at creation time.")
public void createMultipleDistributionSetsWithImplicitType() {
List<DistributionSet> sets = new ArrayList<>();
for (int i = 0; i < 10; i++) {
sets.add(new JpaDistributionSet("another DS" + i, "X" + i, "", null, null));
}
sets = distributionSetManagement.createDistributionSets(sets);
assertThat(sets).as("Type should be equal to default type of tenant").are(new Condition<DistributionSet>() {
@Override
public boolean matches(final DistributionSet value) {
return value.getType().equals(systemManagement.getTenantMetadata().getDefaultDsType());
}
});
}
@Test
@Description("Verfies that a DS entity cannot be used for creation.")
public void createDistributionSetFailsOnExistingEntity() {
final DistributionSet set = distributionSetManagement
.createDistributionSet(new JpaDistributionSet("newtypesoft", "1", "", null, null));
try {
distributionSetManagement.createDistributionSet(set);
fail("Should not have worked to create based on a persisted entity.");
} catch (final EntityAlreadyExistsException e) {
}
}
@Test
@Description("Checks that metadata for a distribution set can be created.")
public void createDistributionSetMetadata() {
final String knownKey = "dsMetaKnownKey";
final String knownValue = "dsMetaKnownValue";
final DistributionSet ds = TestDataUtil.generateDistributionSet("testDs", softwareManagement,
distributionSetManagement);
final DistributionSetMetadata metadata = new JpaDistributionSetMetadata(knownKey, ds, knownValue);
final JpaDistributionSetMetadata createdMetadata = (JpaDistributionSetMetadata) distributionSetManagement
.createDistributionSetMetadata(metadata);
assertThat(createdMetadata).isNotNull();
assertThat(createdMetadata.getId().getKey()).isEqualTo(knownKey);
assertThat(createdMetadata.getDistributionSet().getId()).isEqualTo(ds.getId());
assertThat(createdMetadata.getValue()).isEqualTo(knownValue);
}
@Test
@Description("Ensures that updates concerning the internal software structure of a DS are not possible if the DS is already assigned.")
public void updateDistributionSetForbiddedWithIllegalUpdate() {
// prepare data
Target target = new JpaTarget("4711");
target = targetManagement.createTarget(target);
SoftwareModule ah2 = new JpaSoftwareModule(appType, "agent-hub2", "1.0.5", null, "");
SoftwareModule os2 = new JpaSoftwareModule(osType, "poky2", "3.0.3", null, "");
DistributionSet ds = TestDataUtil.generateDistributionSet("ds-1", softwareManagement,
distributionSetManagement);
ah2 = softwareManagement.createSoftwareModule(ah2);
os2 = softwareManagement.createSoftwareModule(os2);
// update is allowed as it is still not assigned to a target
ds.addModule(ah2);
ds = distributionSetManagement.updateDistributionSet(ds);
// assign target
deploymentManagement.assignDistributionSet(ds.getId(), target.getControllerId());
ds = distributionSetManagement.findDistributionSetByIdWithDetails(ds.getId());
// description change is still allowed
ds.setDescription("a different desc");
ds = distributionSetManagement.updateDistributionSet(ds);
// description change is still allowed
ds.setName("a new name");
ds = distributionSetManagement.updateDistributionSet(ds);
// description change is still allowed
ds.setVersion("a new version");
ds = distributionSetManagement.updateDistributionSet(ds);
// not allowed as it is assigned now
ds.addModule(os2);
try {
ds = distributionSetManagement.updateDistributionSet(ds);
fail("Expected EntityLockedException");
} catch (final EntityLockedException e) {
}
// not allowed as it is assigned now
ds.removeModule(ds.findFirstModuleByType(appType));
try {
ds = distributionSetManagement.updateDistributionSet(ds);
fail("Expected EntityLockedException");
} catch (final EntityLockedException e) {
}
}
@Test
@Description("Ensures that it is not possible to add a software module to a set that has no type defined.")
public void updateDistributionSetModuleWithUndefinedTypeFails() {
final DistributionSet testSet = new JpaDistributionSet();
final SoftwareModule module = new JpaSoftwareModule(appType, "agent-hub2", "1.0.5", null, "");
// update data
try {
testSet.addModule(module);
fail("Should not have worked as DS type is undefined.");
} catch (final DistributionSetTypeUndefinedException e) {
}
}
@Test
@Description("Ensures that it is not possible to add a software module that is not defined of the DS's type.")
public void updateDistributionSetUnsupportedModuleFails() {
final DistributionSet set = new JpaDistributionSet("agent-hub2", "1.0.5", "desc",
new JpaDistributionSetType("test", "test", "test").addMandatoryModuleType(osType), null);
final SoftwareModule module = new JpaSoftwareModule(appType, "agent-hub2", "1.0.5", null, "");
// update data
try {
set.addModule(module);
fail("Should not have worked as module type is not in DS type.");
} catch (final UnsupportedSoftwareModuleForThisDistributionSetException e) {
}
}
@Test
@Description("Legal updates of a DS, e.g. name or description and module addition, removal while still unassigned.")
public void updateDistributionSet() {
// prepare data
Target target = new JpaTarget("4711");
target = targetManagement.createTarget(target);
SoftwareModule os2 = new JpaSoftwareModule(osType, "poky2", "3.0.3", null, "");
final SoftwareModule app2 = new JpaSoftwareModule(appType, "app2", "3.0.3", null, "");
DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement, distributionSetManagement);
os2 = softwareManagement.createSoftwareModule(os2);
// update data
// legal update of module addition
ds.addModule(os2);
distributionSetManagement.updateDistributionSet(ds);
ds = distributionSetManagement.findDistributionSetByIdWithDetails(ds.getId());
assertThat(ds.findFirstModuleByType(osType)).isEqualTo(os2);
// legal update of module removal
ds.removeModule(ds.findFirstModuleByType(appType));
distributionSetManagement.updateDistributionSet(ds);
ds = distributionSetManagement.findDistributionSetByIdWithDetails(ds.getId());
assertThat(ds.findFirstModuleByType(appType)).isNull();
// Update description
ds.setDescription("a new description");
distributionSetManagement.updateDistributionSet(ds);
ds = distributionSetManagement.findDistributionSetByIdWithDetails(ds.getId());
assertThat(ds.getDescription()).isEqualTo("a new description");
// Update name
ds.setName("a new name");
distributionSetManagement.updateDistributionSet(ds);
ds = distributionSetManagement.findDistributionSetByIdWithDetails(ds.getId());
assertThat(ds.getName()).isEqualTo("a new name");
}
@Test
@WithUser(allSpPermissions = true)
@Description("Checks that metadata for a distribution set can be updated.")
public void updateDistributionSetMetadata() throws InterruptedException {
final String knownKey = "myKnownKey";
final String knownValue = "myKnownValue";
final String knownUpdateValue = "myNewUpdatedValue";
// create a DS
final DistributionSet ds = TestDataUtil.generateDistributionSet("testDs", softwareManagement,
distributionSetManagement);
// initial opt lock revision must be zero
assertThat(ds.getOptLockRevision()).isEqualTo(1L);
// create an DS meta data entry
final DistributionSetMetadata dsMetadata = distributionSetManagement
.createDistributionSetMetadata(new JpaDistributionSetMetadata(knownKey, ds, knownValue));
DistributionSet changedLockRevisionDS = distributionSetManagement.findDistributionSetById(ds.getId());
assertThat(changedLockRevisionDS.getOptLockRevision()).isEqualTo(2L);
// modifying the meta data value
dsMetadata.setValue(knownUpdateValue);
dsMetadata.setKey(knownKey);
((JpaDistributionSetMetadata) dsMetadata).setDistributionSet(changedLockRevisionDS);
Thread.sleep(100);
// update the DS metadata
final JpaDistributionSetMetadata updated = (JpaDistributionSetMetadata) distributionSetManagement
.updateDistributionSetMetadata(dsMetadata);
// we are updating the sw meta data so also modifying the base software
// module so opt lock
// revision must be three
changedLockRevisionDS = distributionSetManagement.findDistributionSetById(ds.getId());
assertThat(changedLockRevisionDS.getOptLockRevision()).isEqualTo(3L);
assertThat(changedLockRevisionDS.getLastModifiedAt()).isGreaterThan(0L);
// verify updated meta data contains the updated value
assertThat(updated).isNotNull();
assertThat(updated.getValue()).isEqualTo(knownUpdateValue);
assertThat(updated.getId().getKey()).isEqualTo(knownKey);
assertThat(updated.getDistributionSet().getId()).isEqualTo(ds.getId());
}
@Test
@Description("Tests that a DS queue is possible where the result is ordered by the target assignment, i.e. assigned first in the list.")
public void findDistributionSetsAllOrderedByLinkTarget() {
final List<JpaDistributionSet> buildDistributionSets = TestDataUtil.generateDistributionSets("dsOrder", 10,
softwareManagement, distributionSetManagement);
final List<Target> buildTargetFixtures = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(5, "tOrder", "someDesc"));
final Iterator<JpaDistributionSet> dsIterator = buildDistributionSets.iterator();
final Iterator<Target> tIterator = buildTargetFixtures.iterator();
final DistributionSet dsFirst = dsIterator.next();
final DistributionSet dsSecond = dsIterator.next();
final DistributionSet dsThree = dsIterator.next();
final DistributionSet dsFour = dsIterator.next();
final Target tFirst = tIterator.next();
final Target tSecond = tIterator.next();
// set assigned
deploymentManagement.assignDistributionSet(dsSecond.getId(), tSecond.getControllerId());
deploymentManagement.assignDistributionSet(dsThree.getId(), tFirst.getControllerId());
// set installed
final ArrayList<Target> installedDSSecond = new ArrayList<>();
installedDSSecond.add(tSecond);
sendUpdateActionStatusToTargets(dsSecond, installedDSSecond, Status.FINISHED, "some message");
deploymentManagement.assignDistributionSet(dsFour.getId(), tSecond.getControllerId());
final DistributionSetFilterBuilder distributionSetFilterBuilder = new DistributionSetFilterBuilder()
.setIsDeleted(false).setIsComplete(true).setSelectDSWithNoTag(Boolean.FALSE);
// target first only has an assigned DS-three so check order correct
final List<DistributionSet> tFirstPin = distributionSetManagement.findDistributionSetsAllOrderedByLinkTarget(
pageReq, distributionSetFilterBuilder, tFirst.getControllerId()).getContent();
assertThat(tFirstPin.get(0)).isEqualTo(dsThree);
assertThat(tFirstPin).hasSize(10);
// target second has installed DS-2 and assigned DS-4 so check order
// correct
final List<DistributionSet> tSecondPin = distributionSetManagement.findDistributionSetsAllOrderedByLinkTarget(
pageReq, distributionSetFilterBuilder, tSecond.getControllerId()).getContent();
assertThat(tSecondPin.get(0)).isEqualTo(dsSecond);
assertThat(tSecondPin.get(1)).isEqualTo(dsFour);
assertThat(tFirstPin).hasSize(10);
}
@Test
@Description("searches for distribution sets based on the various filter options, e.g. name, version, desc., tags.")
public void searchDistributionSetsOnFilters() {
DistributionSetTag dsTagA = tagManagement
.createDistributionSetTag(new JpaDistributionSetTag("DistributionSetTag-A"));
final DistributionSetTag dsTagB = tagManagement
.createDistributionSetTag(new JpaDistributionSetTag("DistributionSetTag-B"));
final DistributionSetTag dsTagC = tagManagement
.createDistributionSetTag(new JpaDistributionSetTag("DistributionSetTag-C"));
final DistributionSetTag dsTagD = tagManagement
.createDistributionSetTag(new JpaDistributionSetTag("DistributionSetTag-D"));
Collection<DistributionSet> ds100Group1 = (Collection) TestDataUtil.generateDistributionSets("", 100,
softwareManagement, distributionSetManagement);
Collection<DistributionSet> ds100Group2 = (Collection) TestDataUtil.generateDistributionSets("test2", 100,
softwareManagement, distributionSetManagement);
DistributionSet dsDeleted = TestDataUtil.generateDistributionSet("deleted", softwareManagement,
distributionSetManagement);
final DistributionSet dsInComplete = distributionSetManagement
.createDistributionSet(new JpaDistributionSet("notcomplete", "1", "", standardDsType, null));
final DistributionSetType newType = distributionSetManagement.createDistributionSetType(
new JpaDistributionSetType("foo", "bar", "test").addMandatoryModuleType(osType)
.addOptionalModuleType(appType).addOptionalModuleType(runtimeType));
final DistributionSet dsNewType = distributionSetManagement
.createDistributionSet(new JpaDistributionSet("newtype", "1", "", newType, dsDeleted.getModules()));
deploymentManagement.assignDistributionSet(dsDeleted,
targetManagement.createTargets(Lists.newArrayList(TestDataUtil.generateTargets(5))));
distributionSetManagement.deleteDistributionSet(dsDeleted);
dsDeleted = distributionSetManagement.findDistributionSetById(dsDeleted.getId());
ds100Group1 = distributionSetManagement.toggleTagAssignment(ds100Group1, dsTagA).getAssignedEntity();
dsTagA = distributionSetTagRepository.findByNameEquals(dsTagA.getName());
ds100Group1 = distributionSetManagement.toggleTagAssignment(ds100Group1, dsTagB).getAssignedEntity();
dsTagA = distributionSetTagRepository.findByNameEquals(dsTagA.getName());
ds100Group2 = distributionSetManagement.toggleTagAssignment(ds100Group2, dsTagA).getAssignedEntity();
dsTagA = distributionSetTagRepository.findByNameEquals(dsTagA.getName());
// check setup
assertThat(distributionSetRepository.findAll()).hasSize(203);
// Find all
List<DistributionSet> expected = new ArrayList<DistributionSet>();
expected.addAll(ds100Group1);
expected.addAll(ds100Group2);
expected.add(dsDeleted);
expected.add(dsInComplete);
expected.add(dsNewType);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, getDistributionSetFilterBuilder().build()).getContent())
.hasSize(203).containsOnly(expected.toArray(new DistributionSet[0]));
DistributionSetFilterBuilder distributionSetFilterBuilder;
// search for not deleted
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsDeleted(Boolean.TRUE);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(1);
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsDeleted(false);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent())
.hasSize(202);
// search for completed
expected = new ArrayList<DistributionSet>();
expected.addAll(ds100Group1);
expected.addAll(ds100Group2);
expected.add(dsDeleted);
expected.add(dsNewType);
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(true);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(202)
.containsOnly(expected.toArray(new DistributionSet[0]));
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.FALSE);
expected = new ArrayList<DistributionSet>();
expected.add(dsInComplete);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(1)
.containsOnly(expected.toArray(new DistributionSet[0]));
// search for type
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setType(newType);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(1);
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setType(standardDsType);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent())
.hasSize(202);
// search for text
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setSearchText("%test2");
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent())
.hasSize(100);
// search for tags
distributionSetFilterBuilder = getDistributionSetFilterBuilder()
.setTagNames(Lists.newArrayList(dsTagA.getName()));
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent())
.hasSize(200);
distributionSetFilterBuilder = getDistributionSetFilterBuilder()
.setTagNames(Lists.newArrayList(dsTagB.getName()));
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent())
.hasSize(100);
distributionSetFilterBuilder = getDistributionSetFilterBuilder()
.setTagNames(Lists.newArrayList(dsTagA.getName(), dsTagB.getName()));
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent())
.hasSize(200);
distributionSetFilterBuilder = getDistributionSetFilterBuilder()
.setTagNames(Lists.newArrayList(dsTagC.getName(), dsTagB.getName()));
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent())
.hasSize(100);
distributionSetFilterBuilder = getDistributionSetFilterBuilder()
.setTagNames(Lists.newArrayList(dsTagC.getName()));
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(0);
// combine deleted and complete
expected = new ArrayList<DistributionSet>();
expected.addAll(ds100Group1);
expected.addAll(ds100Group2);
expected.add(dsNewType);
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setIsDeleted(Boolean.FALSE);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(201)
.containsOnly(expected.toArray(new DistributionSet[0]));
expected = new ArrayList<DistributionSet>();
expected.add(dsInComplete);
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.FALSE);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(1)
.containsOnly(expected.toArray(new DistributionSet[0]));
expected = new ArrayList<DistributionSet>();
expected.add(dsDeleted);
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setIsDeleted(Boolean.TRUE);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(1)
.containsOnly(expected.toArray(new DistributionSet[0]));
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsDeleted(Boolean.TRUE)
.setIsComplete(Boolean.FALSE);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(0);
// combine deleted and complete and type
expected = new ArrayList<>();
expected.addAll(ds100Group1);
expected.addAll(ds100Group2);
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsDeleted(Boolean.FALSE)
.setIsComplete(Boolean.TRUE).setType(standardDsType);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(200)
.containsOnly(expected.toArray(new DistributionSet[0]));
expected = new ArrayList<>();
expected.add(dsDeleted);
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setType(standardDsType).setIsDeleted(Boolean.TRUE);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(1)
.containsOnly(expected.toArray(new DistributionSet[0]));
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsDeleted(Boolean.TRUE)
.setIsComplete(Boolean.FALSE).setType(standardDsType);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(0);
expected = new ArrayList<>();
expected.add(dsNewType);
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setType(newType);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(1)
.containsOnly(expected.toArray(new DistributionSet[0]));
// combine deleted and complete and type and text
expected = new ArrayList<>();
expected.addAll(ds100Group2);
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setType(standardDsType).setSearchText("%test2");
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(100)
.containsOnly(expected.toArray(new DistributionSet[0]));
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setIsDeleted(Boolean.TRUE).setType(standardDsType).setSearchText("%test2");
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(0);
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setType(standardDsType).setSearchText("%test2")
.setIsComplete(false).setIsDeleted(false);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(0);
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setType(newType).setSearchText("%test2")
.setIsComplete(Boolean.TRUE).setIsDeleted(false);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(0);
// combine deleted and complete and type and text and tag
expected = new ArrayList<>();
expected.addAll(ds100Group2);
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(true).setType(standardDsType)
.setSearchText("%test2").setTagNames(Lists.newArrayList(dsTagA.getName()));
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(100)
.containsOnly(expected.toArray(new DistributionSet[0]));
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setType(standardDsType).setSearchText("%test2")
.setTagNames(Lists.newArrayList(dsTagA.getName())).setIsComplete(Boolean.FALSE)
.setIsDeleted(Boolean.FALSE);
assertThat(distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getContent()).hasSize(0);
}
private DistributionSetFilterBuilder getDistributionSetFilterBuilder() {
return new DistributionSetFilterBuilder();
}
private List<Target> sendUpdateActionStatusToTargets(final DistributionSet dsA, final Iterable<Target> targs,
final Status status, final String... msgs) {
final List<Target> result = new ArrayList<>();
for (final Target t : targs) {
final List<Action> findByTarget = actionRepository.findByTarget((JpaTarget) t);
for (final Action action : findByTarget) {
result.add(sendUpdateActionStatusToTarget(status, action, t, msgs));
}
}
return result;
}
@Test
@Description("Simple DS load without the related data that should be loaded lazy.")
public void findDistributionSetsWithoutLazy() {
TestDataUtil.generateDistributionSets(20, softwareManagement, distributionSetManagement);
assertThat(distributionSetManagement.findDistributionSetsByDeletedAndOrCompleted(pageReq, false, true))
.hasSize(20);
}
@Test
@Description("Deltes a DS that is no in use. Expected behaviour is a hard delete on the database.")
public void deleteUnassignedDistributionSet() {
DistributionSet ds1 = TestDataUtil.generateDistributionSet("ds-1", softwareManagement,
distributionSetManagement);
DistributionSet ds2 = TestDataUtil.generateDistributionSet("ds-2", softwareManagement,
distributionSetManagement);
ds1 = distributionSetManagement.findDistributionSetByNameAndVersion(ds1.getName(), ds1.getVersion());
ds2 = distributionSetManagement.findDistributionSetByNameAndVersion(ds2.getName(), ds2.getVersion());
// delete a ds
assertThat(distributionSetRepository.findAll()).hasSize(2);
distributionSetManagement.deleteDistributionSet(ds1.getId());
// not assigned so not marked as deleted but fully deleted
assertThat(distributionSetRepository.findAll()).hasSize(1);
assertThat(distributionSetManagement
.findDistributionSetsByDeletedAndOrCompleted(pageReq, Boolean.FALSE, Boolean.TRUE).getTotalElements())
.isEqualTo(1);
}
@Test
@Description("Queries and loads the metadata related to a given software module.")
public void findAllDistributionSetMetadataByDsId() {
// create a DS
DistributionSet ds1 = TestDataUtil.generateDistributionSet("testDs1", softwareManagement,
distributionSetManagement);
DistributionSet ds2 = TestDataUtil.generateDistributionSet("testDs2", softwareManagement,
distributionSetManagement);
for (int index = 0; index < 10; index++) {
ds1 = distributionSetManagement
.createDistributionSetMetadata(new JpaDistributionSetMetadata("key" + index, ds1, "value" + index))
.getDistributionSet();
}
for (int index = 0; index < 20; index++) {
ds2 = distributionSetManagement
.createDistributionSetMetadata(new JpaDistributionSetMetadata("key" + index, ds2, "value" + index))
.getDistributionSet();
}
final Page<DistributionSetMetadata> metadataOfDs1 = distributionSetManagement
.findDistributionSetMetadataByDistributionSetId(ds1.getId(), new PageRequest(0, 100));
final Page<DistributionSetMetadata> metadataOfDs2 = distributionSetManagement
.findDistributionSetMetadataByDistributionSetId(ds2.getId(), new PageRequest(0, 100));
assertThat(metadataOfDs1.getNumberOfElements()).isEqualTo(10);
assertThat(metadataOfDs1.getTotalElements()).isEqualTo(10);
assertThat(metadataOfDs2.getNumberOfElements()).isEqualTo(20);
assertThat(metadataOfDs2.getTotalElements()).isEqualTo(20);
}
@Test
@Description("Deltes a DS that is no in use. Expected behaviour is a soft delete on the database, i.e. only marked as "
+ "deleted, kept eas refernce and unavailable for future use..")
public void deleteAssignedDistributionSet() {
DistributionSet ds1 = TestDataUtil.generateDistributionSet("ds-1", softwareManagement,
distributionSetManagement);
DistributionSet ds2 = TestDataUtil.generateDistributionSet("ds-2", softwareManagement,
distributionSetManagement);
DistributionSet dsAssigned = TestDataUtil.generateDistributionSet("ds-3", softwareManagement,
distributionSetManagement);
ds1 = distributionSetManagement.findDistributionSetByNameAndVersion(ds1.getName(), ds1.getVersion());
ds2 = distributionSetManagement.findDistributionSetByNameAndVersion(ds2.getName(), ds2.getVersion());
// create assigned DS
dsAssigned = distributionSetManagement.findDistributionSetByNameAndVersion(dsAssigned.getName(),
dsAssigned.getVersion());
final Target target = new JpaTarget("4712");
final Target savedTarget = targetManagement.createTarget(target);
final List<Target> toAssign = new ArrayList<>();
toAssign.add(savedTarget);
deploymentManagement.assignDistributionSet(dsAssigned, toAssign);
// delete a ds
assertThat(distributionSetRepository.findAll()).hasSize(3);
distributionSetManagement.deleteDistributionSet(dsAssigned.getId());
// not assigned so not marked as deleted
assertThat(distributionSetRepository.findAll()).hasSize(3);
assertThat(distributionSetManagement
.findDistributionSetsByDeletedAndOrCompleted(pageReq, Boolean.FALSE, Boolean.TRUE).getTotalElements())
.isEqualTo(2);
}
private Target sendUpdateActionStatusToTarget(final Status status, final Action updActA, final Target t,
final String... msgs) {
updActA.setStatus(status);
final ActionStatus statusMessages = new JpaActionStatus();
statusMessages.setAction(updActA);
statusMessages.setOccurredAt(System.currentTimeMillis());
statusMessages.setStatus(status);
for (final String msg : msgs) {
statusMessages.addMessage(msg);
}
controllerManagament.addUpdateActionStatus(statusMessages);
return targetManagement.findTargetByControllerID(t.getControllerId());
}
}

View File

@@ -0,0 +1,599 @@
/**
* 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;
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.api.Assertions.fail;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.TestDataUtil;
import org.eclipse.hawkbit.WithSpringAuthorityRule;
import org.eclipse.hawkbit.WithUser;
import org.eclipse.hawkbit.report.model.DataReportSeries;
import org.eclipse.hawkbit.report.model.DataReportSeriesItem;
import org.eclipse.hawkbit.report.model.InnerOuterDataReportSeries;
import org.eclipse.hawkbit.report.model.SeriesTime;
import org.eclipse.hawkbit.repository.ReportManagement.DateTypes;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
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.DistributionSet;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.junit.After;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.auditing.AuditingHandler;
import org.springframework.data.auditing.CurrentDateTimeProvider;
import org.springframework.data.auditing.DateTimeProvider;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import com.google.common.collect.Lists;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("Report Management")
public class ReportManagementTest extends AbstractIntegrationTest {
@Autowired
private ReportManagement reportManagement;
@Autowired
private AuditingHandler auditingHandler;
@After
public void afterTest() {
auditingHandler.setDateTimeProvider(CurrentDateTimeProvider.INSTANCE);
}
@Test
@Description("Tests correct statistics calculation including a correct cache evict.")
public void targetsCreatedOverPeriod() {
// the maximum months going back from now
// create more targets than asking the report so we can check if the
// report is returning the
// correct timeframe
final int maxMonthBackAmountCreateTargets = 10;
final int maxMonthBackAmountReportTargets = 4;
final DynamicDateTimeProvider dynamicDateTimeProvider = new DynamicDateTimeProvider();
auditingHandler.setDateTimeProvider(dynamicDateTimeProvider);
for (int month = 0; month < maxMonthBackAmountCreateTargets; month++) {
dynamicDateTimeProvider.nowMinusMonths(month);
targetManagement.createTarget(new JpaTarget("t" + month));
}
final LocalDateTime to = LocalDateTime.now();
final LocalDateTime from = to.minusMonths(maxMonthBackAmountReportTargets);
DataReportSeries<LocalDate> targetsCreatedOverPeriod = reportManagement
.targetsCreatedOverPeriod(DateTypes.perMonth(), from, to);
// +1 because we go back #maxMonthBackAmountReportTargets but in the
// report the current month
// is included for sure, so from this month we go back
assertThat(targetsCreatedOverPeriod.getData()).as("created over period has wrong size")
.hasSize(maxMonthBackAmountReportTargets + 1);
for (final DataReportSeriesItem<LocalDate> reportItem : targetsCreatedOverPeriod.getData()) {
// only one target is created for each month
assertThat(reportItem.getData().intValue()).as("Target for each month").isEqualTo(1);
}
// check cache evict
for (int month = 0; month < maxMonthBackAmountCreateTargets; month++) {
dynamicDateTimeProvider.nowMinusMonths(month);
targetManagement.createTarget(new JpaTarget("t2" + month));
}
targetsCreatedOverPeriod = reportManagement.targetsCreatedOverPeriod(DateTypes.perMonth(), from, to);
for (final DataReportSeriesItem<LocalDate> reportItem : targetsCreatedOverPeriod.getData()) {
assertThat(reportItem.getData().intValue()).as("Target for each month").isEqualTo(2);
}
}
@Test
@Description("Tests correct statistics calculation including a correct cache evict.")
public void targetsFeedbackOverPeriod() {
// the maximum months going back from now
// create more targets than asking the report so we can check if the
// report is returning the
// correct timeframe
final int maxMonthBackAmountCreateTargets = 10;
final int maxMonthBackAmountReportTargets = 4;
final LocalDateTime to = LocalDateTime.now();
final LocalDateTime from = to.minusMonths(maxMonthBackAmountReportTargets);
final DistributionSet distributionSet = TestDataUtil.generateDistributionSet("ds", softwareManagement,
distributionSetManagement);
final DynamicDateTimeProvider dynamicDateTimeProvider = new DynamicDateTimeProvider();
auditingHandler.setDateTimeProvider(dynamicDateTimeProvider);
for (int month = 0; month < maxMonthBackAmountCreateTargets; month++) {
dynamicDateTimeProvider.nowMinusMonths(month);
final Target createTarget = targetManagement.createTarget(new JpaTarget("t" + month));
final DistributionSetAssignmentResult result = deploymentManagement.assignDistributionSet(distributionSet,
Lists.newArrayList(createTarget));
controllerManagament.registerRetrieved(
deploymentManagement.findActionWithDetails(result.getActions().get(0)),
"Controller retrieved update action and should start now the download.");
}
DataReportSeries<LocalDate> feedbackReceivedOverTime = reportManagement
.feedbackReceivedOverTime(DateTypes.perMonth(), from, to);
// +1 because we go back #maxMonthBackAmountReportTargets but in the
// report the current month
// is included for sure, so from this month we go back
assertThat(feedbackReceivedOverTime.getData()).as("feedback receiver has wrong data size")
.hasSize(maxMonthBackAmountReportTargets + 1);
for (final DataReportSeriesItem<LocalDate> reportItem : feedbackReceivedOverTime.getData()) {
// only one target feedback is created for each month
assertThat(reportItem.getData().intValue()).as("data size is wrong").isEqualTo(1);
}
// check cache evict
for (int month = 0; month < maxMonthBackAmountCreateTargets; month++) {
dynamicDateTimeProvider.nowMinusMonths(month);
final Target createTarget = targetManagement.createTarget(new JpaTarget("t2" + month));
final DistributionSetAssignmentResult result = deploymentManagement.assignDistributionSet(distributionSet,
Lists.newArrayList(createTarget));
controllerManagament.registerRetrieved(
deploymentManagement.findActionWithDetails(result.getActions().get(0)),
"Controller retrieved update action and should start now the download.");
}
feedbackReceivedOverTime = reportManagement.feedbackReceivedOverTime(DateTypes.perMonth(), from, to);
for (final DataReportSeriesItem<LocalDate> reportItem : feedbackReceivedOverTime.getData()) {
assertThat(reportItem.getData().intValue()).as("report item has wrong data size").isEqualTo(2);
}
}
@Test
@Description("Tests correct statistics calculation including a correct cache evict.")
public void distributionUsageInstalled() {
final Target knownTarget1 = targetManagement.createTarget(new JpaTarget("t1"));
final Target knownTarget2 = targetManagement.createTarget(new JpaTarget("t2"));
final Target knownTarget3 = targetManagement.createTarget(new JpaTarget("t3"));
final Target knownTarget4 = targetManagement.createTarget(new JpaTarget("t4"));
final Target knownTarget5 = targetManagement.createTarget(new JpaTarget("t5"));
final SoftwareModule ah = softwareManagement
.createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, ""));
final SoftwareModule jvm = softwareManagement
.createSoftwareModule(new JpaSoftwareModule(runtimeType, "oracle-jre", "1.7.2", null, ""));
final SoftwareModule os = softwareManagement
.createSoftwareModule(new JpaSoftwareModule(osType, "poky", "3.0.2", null, ""));
final DistributionSet distributionSet1 = distributionSetManagement
.createDistributionSet(TestDataUtil.buildDistributionSet("ds1", "0.0.0", standardDsType, os, jvm, ah));
final DistributionSet distributionSet11 = distributionSetManagement
.createDistributionSet(TestDataUtil.buildDistributionSet("ds1", "0.0.1", standardDsType, os, jvm, ah));
final DistributionSet distributionSet2 = distributionSetManagement
.createDistributionSet(TestDataUtil.buildDistributionSet("ds2", "0.0.2", standardDsType, os, jvm, ah));
final DistributionSet distributionSet3 = distributionSetManagement
.createDistributionSet(TestDataUtil.buildDistributionSet("ds3", "0.0.3", standardDsType, os, jvm, ah));
// ds1(0.0.0)=[target1,target2], ds1(0.0.1)=[target3]
deploymentManagement.assignDistributionSet(distributionSet1.getId(), knownTarget1.getControllerId());
deploymentManagement.assignDistributionSet(distributionSet1.getId(), knownTarget2.getControllerId());
deploymentManagement.assignDistributionSet(distributionSet11.getId(), knownTarget3.getControllerId());
// ds2=[target4]
deploymentManagement.assignDistributionSet(distributionSet2.getId(), knownTarget4.getControllerId());
// ds3=[target5] --> ONLY ASSIGNED AND NOT INSTALLED
deploymentManagement.assignDistributionSet(distributionSet3.getId(), knownTarget5.getControllerId());
// set installed status
sendUpdateActionStatusToTargets(distributionSet1, Lists.newArrayList(knownTarget1, knownTarget2),
Status.FINISHED, "some message");
sendUpdateActionStatusToTargets(distributionSet11, Lists.newArrayList(knownTarget3), Status.FINISHED,
"some message");
sendUpdateActionStatusToTargets(distributionSet2, Lists.newArrayList(knownTarget4), Status.FINISHED,
"some message");
List<InnerOuterDataReportSeries<String>> distributionUsage = reportManagement.distributionUsageInstalled(100);
for (final InnerOuterDataReportSeries<String> innerOuterDataReportSeries : distributionUsage) {
// innerseries only have one data of the name and the total count
final DataReportSeriesItem<String> dataReportSeriesItem = innerOuterDataReportSeries.getInnerSeries()
.getData()[0];
if (dataReportSeriesItem.getType().equals("ds1")) {
// total count of three because ds1 has two different versions
assertThat(dataReportSeriesItem.getData()).as("Version/Item type of DistributionSet 1 in statistics")
.isEqualTo(3L);
final DataReportSeriesItem<String>[] outerData = innerOuterDataReportSeries.getOuterSeries().getData();
assertThat(Arrays.stream(outerData).map(DataReportSeriesItem::getType).collect(Collectors.toList()))
.as("versio item contains wrong version").contains("0.0.0", "0.0.1");
} else if (dataReportSeriesItem.getType().equals("ds2")) {
assertThat(dataReportSeriesItem.getData()).as("Version/Item type of DistributionSet 2 in statistics")
.isEqualTo(1L);
final DataReportSeriesItem<String>[] outerData = innerOuterDataReportSeries.getOuterSeries().getData();
assertThat(outerData).as("Version/Item type has wrong size").hasSize(1);
assertThat(outerData[0].getType()).as("Version/Item type of DistributionSet 2 in statistics")
.isEqualTo("0.0.2");
} else if (dataReportSeriesItem.getType().equals("ds3")) {
assertThat(dataReportSeriesItem.getData()).as("Version/Item type of DistributionSet 3 in statistics")
.isEqualTo(0L);
final DataReportSeriesItem<String>[] outerData = innerOuterDataReportSeries.getOuterSeries().getData();
assertThat(outerData).as("Version/Item type has wrong size").hasSize(1);
assertThat(outerData[0].getType()).as("Version/Item type of DistributionSet 3 in statistics")
.isEqualTo("0.0.3");
} else {
fail("no assertion count for distribution set " + dataReportSeriesItem.getType());
}
}
// Test cache evict
final Target knownTarget6 = targetManagement.createTarget(new JpaTarget("t6"));
deploymentManagement.assignDistributionSet(distributionSet1.getId(), knownTarget6.getControllerId());
sendUpdateActionStatusToTargets(distributionSet1, Lists.newArrayList(knownTarget6), Status.FINISHED,
"some message");
distributionUsage = reportManagement.distributionUsageInstalled(100);
for (final InnerOuterDataReportSeries<String> innerOuterDataReportSeries : distributionUsage) {
final DataReportSeriesItem<String> dataReportSeriesItem = innerOuterDataReportSeries.getInnerSeries()
.getData()[0];
if (dataReportSeriesItem.getType().equals("ds1")) {
assertThat(dataReportSeriesItem.getData()).as("Data report item number").isEqualTo(4L);
}
}
}
@Test
@Description("Tests correct statistics calculation including a correct cache evict.")
public void targetStatusReport() {
final long knownErrorCount = 5;
final long knownSyncCount = 4;
final long knownPendingCount = 3;
final long knownRegCount = 2;
final long knownUnknownCount = 1;
createTargetsWithStatus("error", knownErrorCount, TargetUpdateStatus.ERROR);
createTargetsWithStatus("snyc", knownSyncCount, TargetUpdateStatus.IN_SYNC);
createTargetsWithStatus("pending", knownPendingCount, TargetUpdateStatus.PENDING);
createTargetsWithStatus("reg", knownRegCount, TargetUpdateStatus.REGISTERED);
createTargetsWithStatus("unknown", knownUnknownCount, TargetUpdateStatus.UNKNOWN);
DataReportSeries<TargetUpdateStatus> targetStatus = reportManagement.targetStatus();
for (final DataReportSeriesItem<TargetUpdateStatus> reportItem : targetStatus.getData()) {
switch (reportItem.getType()) {
case ERROR:
assertThat(reportItem.getData()).as("ERROR count for targets in statistics").isEqualTo(knownErrorCount);
break;
case IN_SYNC:
assertThat(reportItem.getData()).as("IN_SYNC count for targets in statistics")
.isEqualTo(knownSyncCount);
break;
case PENDING:
assertThat(reportItem.getData()).as("PENDING count for targets in statistics")
.isEqualTo(knownPendingCount);
break;
case REGISTERED:
assertThat(reportItem.getData()).as("REGISTERED count for targets in statistics")
.isEqualTo(knownRegCount);
break;
case UNKNOWN:
assertThat(reportItem.getData()).as("UNKNOWN count for targets in statistics")
.isEqualTo(knownUnknownCount);
break;
default:
fail("missing case for unknown target update status " + reportItem.getType());
}
}
// test cache evict
createTargetsWithStatus("error2", knownErrorCount, TargetUpdateStatus.ERROR);
createTargetsWithStatus("snyc2", knownSyncCount, TargetUpdateStatus.IN_SYNC);
createTargetsWithStatus("pending2", knownPendingCount, TargetUpdateStatus.PENDING);
createTargetsWithStatus("reg2", knownRegCount, TargetUpdateStatus.REGISTERED);
createTargetsWithStatus("unknown2", knownUnknownCount, TargetUpdateStatus.UNKNOWN);
targetStatus = reportManagement.targetStatus();
for (final DataReportSeriesItem<TargetUpdateStatus> reportItem : targetStatus.getData()) {
switch (reportItem.getType()) {
case ERROR:
assertThat(reportItem.getData()).as("ERROR count for targets in statistics")
.isEqualTo(knownErrorCount * 2);
break;
case IN_SYNC:
assertThat(reportItem.getData()).as("IN_SYNC count for targets in statistics")
.isEqualTo(knownSyncCount * 2);
break;
case PENDING:
assertThat(reportItem.getData()).as("PENDING count for targets in statistics")
.isEqualTo(knownPendingCount * 2);
break;
case REGISTERED:
assertThat(reportItem.getData()).as("REGISTERED count for targets in statistics")
.isEqualTo(knownRegCount * 2);
break;
case UNKNOWN:
assertThat(reportItem.getData()).as("UNKNOWN count for targets in statistics")
.isEqualTo(knownUnknownCount * 2);
break;
default:
fail("missing case for unknown target update status " + reportItem.getType());
}
}
}
@Test
@Description("Tests correct statistics calculation including a correct cache evict.")
public void topXDistributionUsage() {
final Target knownTarget1 = targetManagement.createTarget(new JpaTarget("t1"));
final Target knownTarget2 = targetManagement.createTarget(new JpaTarget("t2"));
final Target knownTarget3 = targetManagement.createTarget(new JpaTarget("t3"));
final Target knownTarget4 = targetManagement.createTarget(new JpaTarget("t4"));
final SoftwareModule ah = softwareManagement
.createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, ""));
final SoftwareModule jvm = softwareManagement
.createSoftwareModule(new JpaSoftwareModule(runtimeType, "oracle-jre", "1.7.2", null, ""));
final SoftwareModule os = softwareManagement
.createSoftwareModule(new JpaSoftwareModule(osType, "poky", "3.0.2", null, ""));
final DistributionSet distributionSet1 = distributionSetManagement
.createDistributionSet(TestDataUtil.buildDistributionSet("ds1", "0.0.0", standardDsType, os, jvm, ah));
final DistributionSet distributionSet11 = distributionSetManagement
.createDistributionSet(TestDataUtil.buildDistributionSet("ds1", "0.0.1", standardDsType, os, jvm, ah));
final DistributionSet distributionSet2 = distributionSetManagement
.createDistributionSet(TestDataUtil.buildDistributionSet("ds2", "0.0.2", standardDsType, os, jvm, ah));
final DistributionSet distributionSet3 = distributionSetManagement
.createDistributionSet(TestDataUtil.buildDistributionSet("ds3", "0.0.3", standardDsType, os, jvm, ah));
// ds1(0.0.0)=[target1,target2], ds1(0.0.1)=[target3]
deploymentManagement.assignDistributionSet(distributionSet1.getId(), knownTarget1.getControllerId());
deploymentManagement.assignDistributionSet(distributionSet1.getId(), knownTarget2.getControllerId());
deploymentManagement.assignDistributionSet(distributionSet11.getId(), knownTarget3.getControllerId());
// ds2=[target4]
deploymentManagement.assignDistributionSet(distributionSet2.getId(), knownTarget4.getControllerId());
// expect: ds1(0.0.0)=[target1,target2], ds1(0.0.1)=[target3],
// ds2=[target4], ds3=[]
List<InnerOuterDataReportSeries<String>> distributionUsage = reportManagement.distributionUsageAssigned(100);
for (final InnerOuterDataReportSeries<String> innerOuterDataReportSeries : distributionUsage) {
// innerseries only have one data of the name and the total count
final DataReportSeriesItem<String> dataReportSeriesItem = innerOuterDataReportSeries.getInnerSeries()
.getData()[0];
if (dataReportSeriesItem.getType().equals("ds1")) {
// total count of three because ds1 has two different versions
assertThat(dataReportSeriesItem.getData()).as("Total count of DistributionSet 1 in statistics")
.isEqualTo(3L);
final DataReportSeriesItem<String>[] outerData = innerOuterDataReportSeries.getOuterSeries().getData();
assertThat(Arrays.stream(outerData).map(DataReportSeriesItem::getType).collect(Collectors.toList()))
.as("Out series contains wrong version").contains("0.0.0", "0.0.1");
} else if (dataReportSeriesItem.getType().equals("ds2")) {
assertThat(dataReportSeriesItem.getData()).as("Total count of DistributionSet 2 in statistics")
.isEqualTo(1L);
final DataReportSeriesItem<String>[] outerData = innerOuterDataReportSeries.getOuterSeries().getData();
assertThat(outerData).as("out series has wrong size").hasSize(1);
assertThat(outerData[0].getType()).as("Version/Item type of DistributionSet 2 in statistics")
.isEqualTo("0.0.2");
} else if (dataReportSeriesItem.getType().equals("ds3")) {
assertThat(dataReportSeriesItem.getData()).as("Total count of DistributionSet 3 in statistics")
.isEqualTo(0L);
final DataReportSeriesItem<String>[] outerData = innerOuterDataReportSeries.getOuterSeries().getData();
assertThat(outerData).as("out series has wrong size").hasSize(1);
assertThat(outerData[0].getType()).as("Version/Item type of DistributionSet 3 in statistics")
.isEqualTo("0.0.3");
} else {
fail("no assertion count for distribution set " + dataReportSeriesItem.getType());
}
}
// test cache evict
final Target knownTarget5 = targetManagement.createTarget(new JpaTarget("t5"));
deploymentManagement.assignDistributionSet(distributionSet1.getId(), knownTarget5.getControllerId());
distributionUsage = reportManagement.distributionUsageAssigned(100);
for (final InnerOuterDataReportSeries<String> innerOuterDataReportSeries : distributionUsage) {
final DataReportSeriesItem<String> dataReportSeriesItem = innerOuterDataReportSeries.getInnerSeries()
.getData()[0];
if (dataReportSeriesItem.getType().equals("ds1")) {
assertThat(dataReportSeriesItem.getData()).as("Total count of DistributionSet 1 in statistics")
.isEqualTo(4L);
}
}
}
@Test
@Description("Tests correct statistics calculation including a correct cache evict.")
public void lastPollTargets() {
// --- prepare ---
final LocalDateTime now = LocalDateTime.now();
final int knownTargetsPollLastHour = 2;
final int knownTargetsPollLastDay = 3;
final int knownTargetsPollLastWeek = 4;
final int knownTargetsPollLastMonth = 5;
final int knownTargetsPollLastYear = 6;
final int knownTargetsNeverPoll = 7;
// never
createTargets("neverPoll", knownTargetsNeverPoll, null);
// hour
createTargets("hourPoll", knownTargetsPollLastHour, now.minusMinutes(59));
// day
createTargets("dayPoll", knownTargetsPollLastDay, now.minusHours(23));
// week
createTargets("weekPoll", knownTargetsPollLastWeek, now.minusDays(6));
// month
createTargets("monthPoll", knownTargetsPollLastMonth, now.minusWeeks(3));
// year
createTargets("yearPoll", knownTargetsPollLastYear, now.minusMonths(11));
// --- Test ---
DataReportSeries<SeriesTime> targetsNotLastPoll = reportManagement.targetsLastPoll();
DataReportSeriesItem<SeriesTime>[] data = targetsNotLastPoll.getData();
// --- Verfiy ---
// verify hour
assertThat(data[0].getType()).as("Series time").isEqualTo(SeriesTime.HOUR);
assertThat(data[0].getData()).as("Targets poll last hour").isEqualTo((long) knownTargetsPollLastHour);
// verify day
assertThat(data[1].getType()).as("Series time").isEqualTo(SeriesTime.DAY);
assertThat(data[1].getData()).as("Targets poll last day").isEqualTo((long) knownTargetsPollLastDay);
// verify week
assertThat(data[2].getType()).as("Series time").isEqualTo(SeriesTime.WEEK);
assertThat(data[2].getData()).as("Targets poll last week").isEqualTo((long) knownTargetsPollLastWeek);
// test cache evict
createTargets("hourPoll2", knownTargetsPollLastHour, now.minusMinutes(59));
targetsNotLastPoll = reportManagement.targetsLastPoll();
data = targetsNotLastPoll.getData();
assertThat(data[0].getType()).as("Series time").isEqualTo(SeriesTime.HOUR);
assertThat(data[0].getData()).as("Targets poll last hour").isEqualTo((long) knownTargetsPollLastHour * 2);
}
@Test
@WithUser(tenantId = "mytenant", allSpPermissions = true)
@Description("Ensures that targets created report is tenant aware and only creates a report for the current tenant.")
public void targetsCreatedOverPeriodMultiTenancyAware() throws Exception {
final int targetCreateAmount = 10;
// create targets for another tenant
securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", "anotherTenant"), () -> {
for (int index = 0; index < targetCreateAmount; index++) {
targetManagement.createTarget(new JpaTarget("t" + index));
}
return null;
});
// ensure targets has been created for 'anotherTenant'
final Slice<Target> targetsForAnotherTenant = securityRule.runAs(
WithSpringAuthorityRule.withUserAndTenant("user", "anotherTenant"),
() -> targetManagement.findTargetsAll(new PageRequest(0, 1000)));
assertThat(targetsForAnotherTenant).as("targets has wrong size").hasSize(targetCreateAmount);
final LocalDateTime to = LocalDateTime.now();
final LocalDateTime from = to.minusMonths(targetCreateAmount);
// now retrieve the report for the 'mytenant'
final DataReportSeries<LocalDate> targetsCreatedOverPeriod = reportManagement
.targetsCreatedOverPeriod(DateTypes.perMonth(), from, to);
assertThat(targetsCreatedOverPeriod.getData()).as("final no targets should final be created for this tenant")
.hasSize(0);
}
private void createTargets(final String prefix, final int amount, final LocalDateTime lastTargetQuery) {
for (int index = 0; index < amount; index++) {
final Target target = new JpaTarget(prefix + index);
final JpaTarget createTarget = (JpaTarget) targetManagement.createTarget(target);
if (lastTargetQuery != null) {
final JpaTargetInfo targetInfo = (JpaTargetInfo) createTarget.getTargetInfo();
targetInfo.setNew(false);
targetInfo
.setLastTargetQuery(lastTargetQuery.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
targetInfoRepository.save(targetInfo);
}
}
}
private void createTargetsWithStatus(final String prefix, final long amount, final TargetUpdateStatus status) {
for (int index = 0; index < amount; index++) {
final JpaTarget target = new JpaTarget(prefix + index);
final Target sTarget = targetRepository.save(target);
final JpaTargetInfo targetInfo = (JpaTargetInfo) sTarget.getTargetInfo();
targetInfo.setUpdateStatus(status);
targetInfoRepository.save(targetInfo);
}
}
private List<Target> sendUpdateActionStatusToTargets(final DistributionSet dsA, final Iterable<Target> targs,
final Status status, final String... msgs) {
final List<Target> result = new ArrayList<>();
for (final Target t : targs) {
final List<Action> findByTarget = actionRepository.findByTarget((JpaTarget) t);
for (final Action action : findByTarget) {
result.add(sendUpdateActionStatusToTarget(status, action, t, msgs));
}
}
return result;
}
private Target sendUpdateActionStatusToTarget(final Status status, final Action updActA, final Target t,
final String... msgs) {
updActA.setStatus(status);
final ActionStatus statusMessages = new JpaActionStatus();
statusMessages.setAction(updActA);
statusMessages.setOccurredAt(System.currentTimeMillis());
statusMessages.setStatus(status);
for (final String msg : msgs) {
statusMessages.addMessage(msg);
}
controllerManagament.addUpdateActionStatus(statusMessages);
return targetManagement.findTargetByControllerID(t.getControllerId());
}
private class DynamicDateTimeProvider implements DateTimeProvider {
private Calendar datetime = Calendar.getInstance();
/*
* (non-Javadoc)
*
* @see org.springframework.data.auditing.DateTimeProvider#getNow()
*/
@Override
public Calendar getNow() {
return datetime;
}
public void now() {
datetime = Calendar.getInstance();
}
public void nowMinusMonths(final int amount) {
datetime = Calendar.getInstance();
datetime.add(Calendar.MONTH, -amount);
}
/**
* @param datetime
* the datetime to set
*/
public void setDatetime(final Calendar datetime) {
this.datetime = datetime;
}
}
}

View File

@@ -0,0 +1,151 @@
/**
* 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;
import static org.fest.assertions.api.Assertions.assertThat;
import java.io.ByteArrayInputStream;
import java.util.List;
import java.util.Random;
import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB;
import org.eclipse.hawkbit.TestDataUtil;
import org.eclipse.hawkbit.WithSpringAuthorityRule;
import org.eclipse.hawkbit.report.model.TenantUsage;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Target;
import org.junit.Test;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("System Management")
public class SystemManagementTest extends AbstractIntegrationTestWithMongoDB {
@Test
@Description("Ensures that findTenants returns all tenants and not only restricted to the tenant which currently is logged in")
public void findTenantsReturnsAllTenantsNotOnlyWhichLoggedIn() throws Exception {
assertThat(systemManagement.findTenants()).hasSize(1);
createTestTenantsForSystemStatistics(2, 0, 0, 0);
assertThat(systemManagement.findTenants()).hasSize(3);
}
@Test
@Description("Checks that the system report calculates correctly the artifact size of all tenants in the system. It ignores deleted software modules with their artifacts.")
public void systemUsageReportCollectsArtifactsOfAllTenants() throws Exception {
// Prepare tenants
createTestTenantsForSystemStatistics(2, 1234, 0, 0);
// overall data
assertThat(systemManagement.getSystemUsageStatistics().getOverallArtifacts()).isEqualTo(2);
assertThat(systemManagement.getSystemUsageStatistics().getOverallArtifactVolumeInBytes()).isEqualTo(1234 * 2);
// per tenant data
final List<TenantUsage> tenants = systemManagement.getSystemUsageStatistics().getTenants();
assertThat(tenants).hasSize(3);
assertThat(tenants).containsOnly(new TenantUsage("default"),
new TenantUsage("tenant0").setArtifacts(1).setOverallArtifactVolumeInBytes(1234),
new TenantUsage("tenant1").setArtifacts(1).setOverallArtifactVolumeInBytes(1234));
}
@Test
@Description("Checks that the system report calculates correctly the targets size of all tenants in the system")
public void systemUsageReportCollectsTargetsOfAllTenants() throws Exception {
// Prepare tenants
createTestTenantsForSystemStatistics(2, 0, 100, 0);
// overall data
assertThat(systemManagement.getSystemUsageStatistics().getOverallTargets()).isEqualTo(200);
assertThat(systemManagement.getSystemUsageStatistics().getOverallActions()).isEqualTo(0);
// per tenant data
final List<TenantUsage> tenants = systemManagement.getSystemUsageStatistics().getTenants();
assertThat(tenants).hasSize(3);
assertThat(tenants).containsOnly(new TenantUsage("default"), new TenantUsage("tenant0").setTargets(100),
new TenantUsage("tenant1").setTargets(100));
}
@Test
@Description("Checks that the system report calculates correctly the actions size of all tenants in the system")
public void systemUsageReportCollectsActionsOfAllTenants() throws Exception {
// Prepare tenants
createTestTenantsForSystemStatistics(2, 0, 100, 2);
// 2 tenants, 100 targets each, 2 deployments per target => 400
assertThat(systemManagement.getSystemUsageStatistics().getOverallActions()).isEqualTo(400);
// per tenant data
final List<TenantUsage> tenants = systemManagement.getSystemUsageStatistics().getTenants();
assertThat(tenants).hasSize(3);
assertThat(tenants).containsOnly(new TenantUsage("default"),
new TenantUsage("tenant0").setTargets(100).setActions(200),
new TenantUsage("tenant1").setTargets(100).setActions(200));
}
private byte[] createTestTenantsForSystemStatistics(final int tenants, final int artifactSize, final int targets,
final int updates) throws Exception {
final Random randomgen = new Random();
final byte random[] = new byte[artifactSize];
randomgen.nextBytes(random);
for (int i = 0; i < tenants; i++) {
final String tenantname = "tenant" + i;
securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("bumlux", tenantname), () -> {
systemManagement.getTenantMetadata(tenantname);
if (artifactSize > 0) {
createTestArtifact(random);
createDeletedTestArtifact(random);
}
if (targets > 0) {
final List<Target> createdTargets = createTestTargets(targets);
if (updates > 0) {
for (int x = 0; x < updates; x++) {
final DistributionSet ds = TestDataUtil.generateDistributionSet("to be deployed" + x,
softwareManagement, distributionSetManagement, true);
deploymentManagement.assignDistributionSet(ds, createdTargets);
}
}
}
return null;
});
}
return random;
}
private List<Target> createTestTargets(final int targets) {
return targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(targets, "testTargetOfTenant", "testTargetOfTenant"));
}
private void createTestArtifact(final byte[] random) {
JpaSoftwareModule sm = new JpaSoftwareModule(softwareManagement.findSoftwareModuleTypeByKey("os"), "name 1",
"version 1", null, null);
sm = softwareModuleRepository.save(sm);
artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm.getId(), "file1", false);
}
private void createDeletedTestArtifact(final byte[] random) {
final DistributionSet ds = TestDataUtil.generateDistributionSet("deleted garbage", softwareManagement,
distributionSetManagement, true);
ds.getModules().stream().forEach(module -> {
artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), module.getId(), "file1", false);
softwareManagement.deleteSoftwareModule(module);
});
}
}

View File

@@ -0,0 +1,474 @@
/**
* 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;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.TestDataUtil;
import org.eclipse.hawkbit.repository.DistributionSetFilter.DistributionSetFilterBuilder;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult;
import org.eclipse.hawkbit.repository.model.Tag;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
/**
* Test class for {@link TagManagement}.
*
*/
@Features("Component Tests - Repository")
@Stories("Tag Management")
public class TagManagementTest extends AbstractIntegrationTest {
public TagManagementTest() {
LOG = LoggerFactory.getLogger(TagManagementTest.class);
}
@Before
public void setup() {
assertThat(targetTagRepository.findAll()).as("Not tags should be available").isEmpty();
}
@Test
@Description("Full DS tag lifecycle tested. Create tags, assign them to sets and delete the tags.")
public void createAndAssignAndDeleteDistributionSetTags() {
final Collection<DistributionSet> dsAs = (Collection) TestDataUtil.generateDistributionSets("DS-A", 20,
softwareManagement, distributionSetManagement);
final Collection<DistributionSet> dsBs = (Collection) TestDataUtil.generateDistributionSets("DS-B", 10,
softwareManagement, distributionSetManagement);
final Collection<DistributionSet> dsCs = (Collection) TestDataUtil.generateDistributionSets("DS-C", 25,
softwareManagement, distributionSetManagement);
final Collection<DistributionSet> dsABs = (Collection) TestDataUtil.generateDistributionSets("DS-AB", 5,
softwareManagement, distributionSetManagement);
final Collection<DistributionSet> dsACs = (Collection) TestDataUtil.generateDistributionSets("DS-AC", 11,
softwareManagement, distributionSetManagement);
final Collection<DistributionSet> dsBCs = (Collection) TestDataUtil.generateDistributionSets("DS-BC", 13,
softwareManagement, distributionSetManagement);
final Collection<DistributionSet> dsABCs = (Collection) TestDataUtil.generateDistributionSets("DS-ABC", 9,
softwareManagement, distributionSetManagement);
final DistributionSetTag tagA = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("A"));
final DistributionSetTag tagB = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("B"));
final DistributionSetTag tagC = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("C"));
final DistributionSetTag tagX = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("X"));
final DistributionSetTag tagY = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("Y"));
distributionSetManagement.toggleTagAssignment(dsAs, tagA);
distributionSetManagement.toggleTagAssignment(dsBs, tagB);
distributionSetManagement.toggleTagAssignment(dsCs, tagC);
distributionSetManagement.toggleTagAssignment(dsABs, tagManagement.findDistributionSetTag(tagA.getName()));
distributionSetManagement.toggleTagAssignment(dsABs, tagManagement.findDistributionSetTag(tagB.getName()));
distributionSetManagement.toggleTagAssignment(dsACs, tagManagement.findDistributionSetTag(tagA.getName()));
distributionSetManagement.toggleTagAssignment(dsACs, tagManagement.findDistributionSetTag(tagC.getName()));
distributionSetManagement.toggleTagAssignment(dsBCs, tagManagement.findDistributionSetTag(tagB.getName()));
distributionSetManagement.toggleTagAssignment(dsBCs, tagManagement.findDistributionSetTag(tagC.getName()));
distributionSetManagement.toggleTagAssignment(dsABCs, tagManagement.findDistributionSetTag(tagA.getName()));
distributionSetManagement.toggleTagAssignment(dsABCs, tagManagement.findDistributionSetTag(tagB.getName()));
distributionSetManagement.toggleTagAssignment(dsABCs, tagManagement.findDistributionSetTag(tagC.getName()));
DistributionSetFilterBuilder distributionSetFilterBuilder;
// search for not deleted
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(true)
.setTagNames(Lists.newArrayList(tagA.getName()));
assertEquals("filter works not correct",
dsAs.spliterator().getExactSizeIfKnown() + dsABs.spliterator().getExactSizeIfKnown()
+ dsACs.spliterator().getExactSizeIfKnown() + dsABCs.spliterator().getExactSizeIfKnown(),
distributionSetManagement.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build())
.getTotalElements());
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(true)
.setTagNames(Lists.newArrayList(tagB.getName()));
assertEquals("filter works not correct",
dsBs.spliterator().getExactSizeIfKnown() + dsABs.spliterator().getExactSizeIfKnown()
+ dsBCs.spliterator().getExactSizeIfKnown() + dsABCs.spliterator().getExactSizeIfKnown(),
distributionSetManagement.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build())
.getTotalElements());
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(true)
.setTagNames(Lists.newArrayList(tagC.getName()));
assertEquals("filter works not correct",
dsCs.spliterator().getExactSizeIfKnown() + dsACs.spliterator().getExactSizeIfKnown()
+ dsBCs.spliterator().getExactSizeIfKnown() + dsABCs.spliterator().getExactSizeIfKnown(),
distributionSetManagement.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build())
.getTotalElements());
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(true)
.setTagNames(Lists.newArrayList(tagX.getName()));
assertEquals("filter works not correct", 0, distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getTotalElements());
assertEquals("wrong tag size", 5, distributionSetTagRepository.findAll().spliterator().getExactSizeIfKnown());
tagManagement.deleteDistributionSetTag(tagY.getName());
assertEquals("wrong tag size", 4, distributionSetTagRepository.findAll().spliterator().getExactSizeIfKnown());
tagManagement.deleteDistributionSetTag(tagX.getName());
assertEquals("wrong tag size", 3, distributionSetTagRepository.findAll().spliterator().getExactSizeIfKnown());
tagManagement.deleteDistributionSetTag(tagB.getName());
assertEquals("wrong tag size", 2, distributionSetTagRepository.findAll().spliterator().getExactSizeIfKnown());
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setTagNames(Lists.newArrayList(tagA.getName()));
assertEquals("filter works not correct",
dsAs.spliterator().getExactSizeIfKnown() + dsABs.spliterator().getExactSizeIfKnown()
+ dsACs.spliterator().getExactSizeIfKnown() + dsABCs.spliterator().getExactSizeIfKnown(),
distributionSetManagement.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build())
.getTotalElements());
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setTagNames(Lists.newArrayList(tagB.getName()));
assertEquals("filter works not correct", 0, distributionSetManagement
.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build()).getTotalElements());
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setTagNames(Lists.newArrayList(tagC.getName()));
assertEquals("filter works not correct",
dsCs.spliterator().getExactSizeIfKnown() + dsACs.spliterator().getExactSizeIfKnown()
+ dsBCs.spliterator().getExactSizeIfKnown() + dsABCs.spliterator().getExactSizeIfKnown(),
distributionSetManagement.findDistributionSetsByFilters(pageReq, distributionSetFilterBuilder.build())
.getTotalElements());
}
private DistributionSetFilterBuilder getDistributionSetFilterBuilder() {
return new DistributionSetFilterBuilder();
}
@Test
@Description("Verifies the toogle mechanism by means on assigning tag if at least on DS in the list does not have"
+ "the tag yet. Unassign if all of them have the tag already.")
public void assignAndUnassignDistributionSetTags() {
final Collection<DistributionSet> groupA = (Collection) TestDataUtil.generateDistributionSets(20,
softwareManagement, distributionSetManagement);
final Collection<DistributionSet> groupB = (Collection) TestDataUtil.generateDistributionSets("unassigned", 20,
softwareManagement, distributionSetManagement);
final DistributionSetTag tag = tagManagement
.createDistributionSetTag(new JpaDistributionSetTag("tag1", "tagdesc1", ""));
// toggle A only -> A is now assigned
DistributionSetTagAssignmentResult result = distributionSetManagement.toggleTagAssignment(groupA, tag);
assertThat(result.getAlreadyAssigned()).isEqualTo(0);
assertThat(result.getAssigned()).isEqualTo(20);
assertThat(result.getAssignedEntity()).containsAll(distributionSetManagement
.findDistributionSetsAll(groupA.stream().map(set -> set.getId()).collect(Collectors.toList())));
assertThat(result.getUnassigned()).isEqualTo(0);
assertThat(result.getUnassignedEntity()).isEmpty();
assertThat(result.getDistributionSetTag()).isEqualTo(tag);
// toggle A+B -> A is still assigned and B is assigned as well
result = distributionSetManagement.toggleTagAssignment(concat(groupA, groupB), tag);
assertThat(result.getAlreadyAssigned()).isEqualTo(20);
assertThat(result.getAssigned()).isEqualTo(20);
assertThat(result.getAssignedEntity()).containsAll(distributionSetManagement
.findDistributionSetsAll(groupB.stream().map(set -> set.getId()).collect(Collectors.toList())));
assertThat(result.getUnassigned()).isEqualTo(0);
assertThat(result.getUnassignedEntity()).isEmpty();
assertThat(result.getDistributionSetTag()).isEqualTo(tag);
// toggle A+B -> both unassigned
result = distributionSetManagement.toggleTagAssignment(concat(groupA, groupB), tag);
assertThat(result.getAlreadyAssigned()).isEqualTo(0);
assertThat(result.getAssigned()).isEqualTo(0);
assertThat(result.getAssignedEntity()).isEmpty();
assertThat(result.getUnassigned()).isEqualTo(40);
assertThat(result.getUnassignedEntity()).containsAll(distributionSetManagement.findDistributionSetsAll(
concat(groupB, groupA).stream().map(set -> set.getId()).collect(Collectors.toList())));
assertThat(result.getDistributionSetTag()).isEqualTo(tag);
}
@Test
@Description("Verifies the toogle mechanism by means on assigning tag if at least on target in the list does not have"
+ "the tag yet. Unassign if all of them have the tag already.")
public void assignAndUnassignTargetTags() {
final List<Target> groupA = targetManagement.createTargets(TestDataUtil.generateTargets(20, ""));
final List<Target> groupB = targetManagement.createTargets(TestDataUtil.generateTargets(20, "groupb"));
final TargetTag tag = tagManagement.createTargetTag(new JpaTargetTag("tag1", "tagdesc1", ""));
// toggle A only -> A is now assigned
TargetTagAssignmentResult result = targetManagement.toggleTagAssignment(groupA, tag);
assertThat(result.getAlreadyAssigned()).isEqualTo(0);
assertThat(result.getAssigned()).isEqualTo(20);
assertThat(result.getAssignedEntity()).containsAll(targetManagement.findTargetsByControllerIDsWithTags(
groupA.stream().map(target -> target.getControllerId()).collect(Collectors.toList())));
assertThat(result.getUnassigned()).isEqualTo(0);
assertThat(result.getUnassignedEntity()).isEmpty();
assertThat(result.getTargetTag()).isEqualTo(tag);
// toggle A+B -> A is still assigned and B is assigned as well
result = targetManagement.toggleTagAssignment(concat(groupA, groupB), tag);
assertThat(result.getAlreadyAssigned()).isEqualTo(20);
assertThat(result.getAssigned()).isEqualTo(20);
assertThat(result.getAssignedEntity()).containsAll(targetManagement.findTargetsByControllerIDsWithTags(
groupB.stream().map(target -> target.getControllerId()).collect(Collectors.toList())));
assertThat(result.getUnassigned()).isEqualTo(0);
assertThat(result.getUnassignedEntity()).isEmpty();
assertThat(result.getTargetTag()).isEqualTo(tag);
// toggle A+B -> both unassigned
result = targetManagement.toggleTagAssignment(concat(groupA, groupB), tag);
assertThat(result.getAlreadyAssigned()).isEqualTo(0);
assertThat(result.getAssigned()).isEqualTo(0);
assertThat(result.getAssignedEntity()).isEmpty();
assertThat(result.getUnassigned()).isEqualTo(40);
assertThat(result.getUnassignedEntity()).containsAll(targetManagement.findTargetsByControllerIDsWithTags(
concat(groupB, groupA).stream().map(target -> target.getControllerId()).collect(Collectors.toList())));
assertThat(result.getTargetTag()).isEqualTo(tag);
}
@SafeVarargs
private final <T> Collection<T> concat(final Collection<T>... targets) {
final List<T> result = new ArrayList<>();
Arrays.asList(targets).forEach(result::addAll);
return result;
}
@Test
@Description("Ensures that all tags are retrieved through repository.")
public void findAllTargetTags() {
final List<JpaTargetTag> tags = createTargetsWithTags();
assertThat(targetTagRepository.findAll()).isEqualTo(targetTagRepository.findAll()).isEqualTo(tags)
.as("Wrong tag size").hasSize(20);
}
@Test
@Description("Ensures that a created tag is persisted in the repository as defined.")
public void createTargetTag() {
final Tag tag = tagManagement.createTargetTag(new JpaTargetTag("kai1", "kai2", "colour"));
assertThat(targetTagRepository.findByNameEquals("kai1").getDescription()).as("wrong tag ed").isEqualTo("kai2");
assertThat(tagManagement.findTargetTag("kai1").getColour()).as("wrong tag found").isEqualTo("colour");
assertThat(tagManagement.findTargetTagById(tag.getId()).getColour()).as("wrong tag found").isEqualTo("colour");
}
@Test
@Description("Ensures that a deleted tag is removed from the repository as defined.")
public void deleteTargetTas() {
// create test data
final Iterable<JpaTargetTag> tags = createTargetsWithTags();
final TargetTag toDelete = tags.iterator().next();
for (final Target target : targetRepository.findAll()) {
assertThat(targetManagement.findTargetByControllerID(target.getControllerId()).getTags())
.contains(toDelete);
}
// delete
tagManagement.deleteTargetTag(toDelete.getName());
// check
for (final Target target : targetRepository.findAll()) {
assertThat(targetManagement.findTargetByControllerID(target.getControllerId()).getTags())
.doesNotContain(toDelete);
}
assertThat(targetTagRepository.findOne(toDelete.getId())).as("No tag should be found").isNull();
assertThat(targetTagRepository.findAll()).as("Wrong target tag size").hasSize(19);
}
@Test
@Description("Tests the name update of a target tag.")
public void updateTargetTag() {
final List<JpaTargetTag> tags = createTargetsWithTags();
// change data
final TargetTag savedAssigned = tags.iterator().next();
savedAssigned.setName("test123");
// persist
tagManagement.updateTargetTag(savedAssigned);
// check data
assertThat(targetTagRepository.findAll()).as("Wrong target tag size").hasSize(tags.size());
assertThat(targetTagRepository.findOne(savedAssigned.getId()).getName()).as("wrong target tag is saved")
.isEqualTo("test123");
assertThat(targetTagRepository.findOne(savedAssigned.getId()).getOptLockRevision())
.as("wrong target tag is saved").isEqualTo(2);
}
@Test
@Description("Ensures that a created tag is persisted in the repository as defined.")
public void createDistributionSetTag() {
final Tag tag = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("kai1", "kai2", "colour"));
assertThat(distributionSetTagRepository.findByNameEquals("kai1").getDescription()).as("wrong tag found")
.isEqualTo("kai2");
assertThat(tagManagement.findDistributionSetTag("kai1").getColour()).as("wrong tag found").isEqualTo("colour");
assertThat(tagManagement.findDistributionSetTagById(tag.getId()).getColour()).as("wrong tag found")
.isEqualTo("colour");
}
@Test
@Description("Ensures that a created tags are persisted in the repository as defined.")
public void createDistributionSetTags() {
final List<DistributionSetTag> tags = createDsSetsWithTags();
assertThat(distributionSetTagRepository.findAll()).as("Wrong size of tags created").hasSize(tags.size());
}
@Test
@Description("Ensures that a deleted tag is removed from the repository as defined.")
public void deleteDistributionSetTag() {
// create test data
final Iterable<DistributionSetTag> tags = createDsSetsWithTags();
final DistributionSetTag toDelete = tags.iterator().next();
for (final DistributionSet set : distributionSetRepository.findAll()) {
assertThat(distributionSetManagement.findDistributionSetByIdWithDetails(set.getId()).getTags())
.as("Wrong tag found").contains(toDelete);
}
// delete
tagManagement.deleteDistributionSetTag(tags.iterator().next().getName());
// check
assertThat(distributionSetTagRepository.findOne(toDelete.getId())).as("Deleted tag should be null").isNull();
assertThat(tagManagement.findAllDistributionSetTags()).as("Wrong size of tags after deletion").hasSize(19);
for (final DistributionSet set : distributionSetRepository.findAll()) {
assertThat(distributionSetManagement.findDistributionSetByIdWithDetails(set.getId()).getTags())
.as("Wrong found tags").doesNotContain(toDelete);
}
}
@Test
@Description("Ensures that a tag cannot be created if one exists already with that name (ecpects EntityAlreadyExistsException).")
public void failedDuplicateTargetTagNameException() {
tagManagement.createTargetTag(new JpaTargetTag("A"));
try {
tagManagement.createTargetTag(new JpaTargetTag("A"));
fail("should not have worked as tag already exists");
} catch (final EntityAlreadyExistsException e) {
}
}
@Test
@Description("Ensures that a tag cannot be updated to a name that already exists on another tag (ecpects EntityAlreadyExistsException).")
public void failedDuplicateTargetTagNameExceptionAfterUpdate() {
tagManagement.createTargetTag(new JpaTargetTag("A"));
final TargetTag tag = tagManagement.createTargetTag(new JpaTargetTag("B"));
tag.setName("A");
try {
tagManagement.updateTargetTag(tag);
fail("should not have worked as tag already exists");
} catch (final EntityAlreadyExistsException e) {
}
}
@Test
@Description("Ensures that a tag cannot be created if one exists already with that name (ecpects EntityAlreadyExistsException).")
public void failedDuplicateDsTagNameException() {
tagManagement.createDistributionSetTag(new JpaDistributionSetTag("A"));
try {
tagManagement.createDistributionSetTag(new JpaDistributionSetTag("A"));
fail("should not have worked as tag already exists");
} catch (final EntityAlreadyExistsException e) {
}
}
@Test
@Description("Ensures that a tag cannot be updated to a name that already exists on another tag (ecpects EntityAlreadyExistsException).")
public void failedDuplicateDsTagNameExceptionAfterUpdate() {
tagManagement.createDistributionSetTag(new JpaDistributionSetTag("A"));
final DistributionSetTag tag = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("B"));
tag.setName("A");
try {
tagManagement.updateDistributionSetTag(tag);
fail("should not have worked as tag already exists");
} catch (final EntityAlreadyExistsException e) {
}
}
@Test
@Description("Tests the name update of a target tag.")
public void updateDistributionSetTag() {
// create test data
final List<DistributionSetTag> tags = createDsSetsWithTags();
// change data
final DistributionSetTag savedAssigned = tags.iterator().next();
savedAssigned.setName("test123");
// persist
tagManagement.updateDistributionSetTag(savedAssigned);
// check data
assertThat(tagManagement.findAllDistributionSetTags()).as("Wrong size of ds tags").hasSize(tags.size());
assertThat(distributionSetTagRepository.findOne(savedAssigned.getId()).getName()).as("Wrong ds tag found")
.isEqualTo("test123");
}
@Test
@Description("Ensures that all tags are retrieved through repository.")
public void findDistributionSetTagsAll() {
final List<DistributionSetTag> tags = createDsSetsWithTags();
// test
assertThat(tagManagement.findAllDistributionSetTags()).as("Wrong size of tags").hasSize(tags.size());
assertThat(distributionSetTagRepository.findAll()).as("Wrong size of tags").hasSize(20);
}
private List<JpaTargetTag> createTargetsWithTags() {
final List<Target> targets = targetManagement.createTargets(TestDataUtil.generateTargets(20));
final Iterable<TargetTag> tags = tagManagement.createTargetTags(TestDataUtil.generateTargetTags(20));
tags.forEach(tag -> targetManagement.toggleTagAssignment(targets, tag));
return targetTagRepository.findAll();
}
private List<DistributionSetTag> createDsSetsWithTags() {
final Collection<DistributionSet> sets = (Collection) TestDataUtil.generateDistributionSets(20,
softwareManagement, distributionSetManagement);
final Iterable<DistributionSetTag> tags = tagManagement
.createDistributionSetTags(TestDataUtil.generateDistributionSetTags(20));
tags.forEach(tag -> distributionSetManagement.toggleTagAssignment(sets, tag));
return tagManagement.findAllDistributionSetTags();
}
}

View File

@@ -0,0 +1,85 @@
/**
* 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;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.junit.Test;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
/**
* Test class for {@link TargetFilterQueryManagement}.
*
*/
@Features("Component Tests - Repository")
@Stories("Target Filter Query Management")
public class TargetFilterQueryManagenmentTest extends AbstractIntegrationTest {
@Test
@Description("Test creation of target filter query.")
public void createTargetFilterQuery() {
final String filterName = "new target filter";
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement
.createTargetFilterQuery(new JpaTargetFilterQuery(filterName, "name==PendingTargets001"));
assertEquals("Retrieved newly created custom target filter", targetFilterQuery,
targetFilterQueryManagement.findTargetFilterQueryByName(filterName));
}
@Test
@Description("Checks if the EntityAlreadyExistsException is thrown if a targetfilterquery with the same name are created more than once.")
public void createDuplicateTargetFilterQuery() {
final String filterName = "new target filter duplicate";
targetFilterQueryManagement
.createTargetFilterQuery(new JpaTargetFilterQuery(filterName, "name==PendingTargets001"));
try {
targetFilterQueryManagement
.createTargetFilterQuery(new JpaTargetFilterQuery(filterName, "name==PendingTargets001"));
fail("should not have worked as query already exists");
} catch (final EntityAlreadyExistsException e) {
}
}
@Test
@Description("Test deletion of target filter query.")
public void deleteTargetFilterQuery() {
final String filterName = "delete_target_filter_query";
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement
.createTargetFilterQuery(new JpaTargetFilterQuery(filterName, "name==PendingTargets001"));
targetFilterQueryManagement.deleteTargetFilterQuery(targetFilterQuery.getId());
assertEquals("Returns null as the target filter is deleted", null,
targetFilterQueryManagement.findTargetFilterQueryById(targetFilterQuery.getId()));
}
@Test
@Description("Test updation of target filter query.")
public void updateTargetFilterQuery() {
final String filterName = "target_filter_01";
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement
.createTargetFilterQuery(new JpaTargetFilterQuery(filterName, "name==PendingTargets001"));
final String newQuery = "status==UNKNOWN";
targetFilterQuery.setQuery(newQuery);
targetFilterQueryManagement.updateTargetFilterQuery(targetFilterQuery);
assertEquals("Returns updated target filter query", newQuery,
targetFilterQueryManagement.findTargetFilterQueryByName(filterName).getQuery());
}
}

View File

@@ -0,0 +1,792 @@
/**
* 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;
import static org.fest.assertions.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.TestDataUtil;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
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.DistributionSet;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetIdName;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.junit.Test;
import org.springframework.data.domain.Slice;
import com.google.common.collect.Lists;
import com.google.common.primitives.Ints;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Step;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("Target Management Searches")
public class TargetManagementSearchTest extends AbstractIntegrationTest {
@Test
@Description("Tests different parameter combinations for target search operations. "
+ "That includes both the test itself, as a count operation with the same filters "
+ "and query definitions by RSQL (named and un-named).")
public void targetSearchWithVariousFilterCombinations() {
final TargetTag targTagX = tagManagement.createTargetTag(new JpaTargetTag("TargTag-X"));
final TargetTag targTagY = tagManagement.createTargetTag(new JpaTargetTag("TargTag-Y"));
final TargetTag targTagZ = tagManagement.createTargetTag(new JpaTargetTag("TargTag-Z"));
final TargetTag targTagW = tagManagement.createTargetTag(new JpaTargetTag("TargTag-W"));
final DistributionSet setA = TestDataUtil.generateDistributionSet("", softwareManagement,
distributionSetManagement);
final DistributionSet installedSet = TestDataUtil.generateDistributionSet("another", softwareManagement,
distributionSetManagement);
final String targetDsAIdPref = "targ-A";
List<Target> targAs = targetManagement.createTargets(
TestDataUtil.buildTargetFixtures(100, targetDsAIdPref, targetDsAIdPref.concat(" description")));
targAs = targetManagement.toggleTagAssignment(targAs, targTagX).getAssignedEntity();
final String targetDsBIdPref = "targ-B";
List<Target> targBs = targetManagement.createTargets(
TestDataUtil.buildTargetFixtures(100, targetDsBIdPref, targetDsBIdPref.concat(" description")));
targBs = targetManagement.toggleTagAssignment(targBs, targTagY).getAssignedEntity();
targBs = targetManagement.toggleTagAssignment(targBs, targTagW).getAssignedEntity();
final String targetDsCIdPref = "targ-C";
List<Target> targCs = targetManagement.createTargets(
TestDataUtil.buildTargetFixtures(100, targetDsCIdPref, targetDsCIdPref.concat(" description")));
targCs = targetManagement.toggleTagAssignment(targCs, targTagZ).getAssignedEntity();
targCs = targetManagement.toggleTagAssignment(targCs, targTagW).getAssignedEntity();
final String targetDsDIdPref = "targ-D";
final List<Target> targDs = targetManagement.createTargets(
TestDataUtil.buildTargetFixtures(100, targetDsDIdPref, targetDsDIdPref.concat(" description")));
final String assignedC = targCs.iterator().next().getControllerId();
deploymentManagement.assignDistributionSet(setA.getId(), assignedC);
final String assignedA = targAs.iterator().next().getControllerId();
deploymentManagement.assignDistributionSet(setA.getId(), assignedA);
final String assignedB = targBs.iterator().next().getControllerId();
deploymentManagement.assignDistributionSet(setA.getId(), assignedB);
final String installedC = targCs.iterator().next().getControllerId();
final Long actionId = deploymentManagement.assignDistributionSet(installedSet.getId(), assignedC).getActions()
.get(0);
// set one installed DS also
final Action action = deploymentManagement.findActionWithDetails(actionId);
action.setStatus(Status.FINISHED);
controllerManagament.addUpdateActionStatus(
new JpaActionStatus((JpaAction) action, Status.FINISHED, System.currentTimeMillis(), "message"));
deploymentManagement.assignDistributionSet(setA.getId(), installedC);
final List<TargetUpdateStatus> unknown = new ArrayList<>();
unknown.add(TargetUpdateStatus.UNKNOWN);
final List<TargetUpdateStatus> pending = new ArrayList<>();
pending.add(TargetUpdateStatus.PENDING);
final List<TargetUpdateStatus> both = new ArrayList<>();
both.add(TargetUpdateStatus.UNKNOWN);
both.add(TargetUpdateStatus.PENDING);
// get final updated version of targets
targAs = targetManagement.findTargetByControllerID(
targAs.stream().map(target -> target.getControllerId()).collect(Collectors.toList()));
targBs = targetManagement.findTargetByControllerID(
targBs.stream().map(target -> target.getControllerId()).collect(Collectors.toList()));
targCs = targetManagement.findTargetByControllerID(
targCs.stream().map(target -> target.getControllerId()).collect(Collectors.toList()));
// try to find several targets with different filter settings
verifyThatRepositoryContains400Targets();
verifyThat200TargetsHaveTagD(targTagW, concat(targBs, targCs));
verifyThat100TargetsContainsGivenTextAndHaveTagAssigned(targTagY, targTagW, targBs);
verifyThat1TargetHasTagHasDescOrNameAndDs(targTagW, setA, targetManagement.findTargetByControllerID(assignedC));
verifyThat0TargetsWithTagAndDescOrNameHasDS(targTagW, setA);
verifyThat0TargetsWithNameOrdescAndDSHaveTag(targTagX, setA);
verifyThat3TargetsHaveDSAssigned(setA,
targetManagement.findTargetByControllerID(Lists.newArrayList(assignedA, assignedB, assignedC)));
verifyThat1TargetWithDescOrNameHasDS(setA, targetManagement.findTargetByControllerID(assignedA));
List<Target> expected = concat(targAs, targBs, targCs, targDs);
expected.removeAll(
targetManagement.findTargetByControllerID(Lists.newArrayList(assignedA, assignedB, assignedC)));
verifyThat397TargetsAreInStatusUnknown(unknown, expected);
expected = concat(targBs, targCs);
expected.removeAll(targetManagement.findTargetByControllerID(Lists.newArrayList(assignedB, assignedC)));
verifyThat198TargetsAreInStatusUnknownAndHaveGivenTags(targTagY, targTagW, unknown, expected);
verfyThat0TargetsAreInStatusUnknownAndHaveDSAssigned(setA, unknown);
expected = concat(targAs);
expected.remove(targetManagement.findTargetByControllerID(assignedA));
verifyThat99TargetsWithNameOrDescriptionAreInGivenStatus(unknown, expected);
expected = concat(targBs);
expected.remove(targetManagement.findTargetByControllerID(assignedB));
verifyThat99TargetsWithGivenNameOrDescAndTagAreInStatusUnknown(targTagW, unknown, expected);
verifyThat3TargetsAreInStatusPending(pending,
targetManagement.findTargetByControllerID(Lists.newArrayList(assignedA, assignedB, assignedC)));
verifyThat3TargetsWithGivenDSAreInPending(setA, pending,
targetManagement.findTargetByControllerID(Lists.newArrayList(assignedA, assignedB, assignedC)));
verifyThat1TargetWithGivenNameOrDescAndDSIsInPending(setA, pending,
targetManagement.findTargetByControllerID(assignedA));
verifyThat1TargetWithGivenNameOrDescAndTagAndDSIsInPending(targTagW, setA, pending,
targetManagement.findTargetByControllerID(assignedB));
verifyThat2TargetsWithGivenTagAndDSIsInPending(targTagW, setA, pending,
targetManagement.findTargetByControllerID(Lists.newArrayList(assignedB, assignedC)));
verifyThat2TargetsWithGivenTagAreInPending(targTagW, pending,
targetManagement.findTargetByControllerID(Lists.newArrayList(assignedB, assignedC)));
verifyThat200targetsWithGivenTagAreInStatusPendingorUnknown(targTagW, both, concat(targBs, targCs));
verfiyThat1TargetAIsInStatusPendingAndHasDSInstalled(installedSet, pending,
targetManagement.findTargetByControllerID(installedC));
}
@Step
private void verfiyThat1TargetAIsInStatusPendingAndHasDSInstalled(final DistributionSet installedSet,
final List<TargetUpdateStatus> pending, final Target expected) {
final TargetIdName expectedIdName = convertToIdName(expected);
final String query = "updatestatus==pending and installedds.name==" + installedSet.getName();
assertThat(targetManagement
.findTargetByFilters(pageReq, pending, null, installedSet.getId(), Boolean.FALSE, new String[0])
.getContent()).as("has number of elements").hasSize(1)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null,
installedSet.getId(), Boolean.FALSE, new String[0])))
.as("and contains the following elements").containsExactly(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, installedSet.getId(),
Boolean.FALSE, new String[0])).as("has number of elements").hasSize(1)
.as("and contains the following elements").containsExactly(expectedIdName)
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThat200targetsWithGivenTagAreInStatusPendingorUnknown(final TargetTag targTagW,
final List<TargetUpdateStatus> both, final List<Target> expected) {
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
final String query = "(updatestatus==pending or updatestatus==unknown) and tag==" + targTagW.getName();
assertThat(targetManagement.findTargetByFilters(pageReq, both, null, null, Boolean.FALSE, targTagW.getName())
.getContent()).as("has number of elements").hasSize(200)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(both, null, null,
Boolean.FALSE, targTagW.getName())))
.as("and contains the following elements").containsAll(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, both, null, null, Boolean.FALSE,
targTagW.getName())).as("has number of elements").hasSize(200).as("and contains the following elements")
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
new JpaTargetFilterQuery("test", query)));
}
private static List<TargetIdName> convertToIdNames(final List<Target> expected) {
return expected.stream()
.map(target -> new TargetIdName(target.getId(), target.getControllerId(), target.getName()))
.collect(Collectors.toList());
}
private static TargetIdName convertToIdName(final Target target) {
return new TargetIdName(target.getId(), target.getControllerId(), target.getName());
}
@Step
private void verifyThat2TargetsWithGivenTagAreInPending(final TargetTag targTagW,
final List<TargetUpdateStatus> pending, final List<Target> expected) {
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
final String query = "updatestatus==pending and tag==" + targTagW.getName();
assertThat(targetManagement.findTargetByFilters(pageReq, pending, null, null, Boolean.FALSE, targTagW.getName())
.getContent()).as("has number of elements").hasSize(2)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null, null,
Boolean.FALSE, targTagW.getName())))
.as("and contains the following elements").containsAll(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, null, Boolean.FALSE,
targTagW.getName())).as("has number of elements").hasSize(2).as("and contains the following elements")
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThat2TargetsWithGivenTagAndDSIsInPending(final TargetTag targTagW, final DistributionSet setA,
final List<TargetUpdateStatus> pending, final List<Target> expected) {
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
final String query = "updatestatus==pending and (assignedds.name==" + setA.getName() + " or installedds.name=="
+ setA.getName() + ") and tag==" + targTagW.getName();
assertThat(targetManagement
.findTargetByFilters(pageReq, pending, null, setA.getId(), Boolean.FALSE, targTagW.getName())
.getContent()).as("has number of elements").hasSize(2)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null, setA.getId(),
Boolean.FALSE, targTagW.getName())))
.as("and contains the following elements").containsAll(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, null, Boolean.FALSE,
targTagW.getName())).as("has number of elements").hasSize(2).as("and contains the following elements")
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThat1TargetWithGivenNameOrDescAndTagAndDSIsInPending(final TargetTag targTagW,
final DistributionSet setA, final List<TargetUpdateStatus> pending, final Target expected) {
final TargetIdName expectedIdName = convertToIdName(expected);
final String query = "updatestatus==pending and (assignedds.name==" + setA.getName() + " or installedds.name=="
+ setA.getName() + ") and (name==*targ-B* or description==*targ-B*) and tag==" + targTagW.getName();
assertThat(targetManagement
.findTargetByFilters(pageReq, pending, "%targ-B%", setA.getId(), Boolean.FALSE, targTagW.getName())
.getContent()).as("has number of elements").hasSize(1)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, "%targ-B%",
setA.getId(), Boolean.FALSE, targTagW.getName())))
.as("and contains the following elements").containsExactly(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, "%targ-B%", setA.getId(), Boolean.FALSE,
targTagW.getName())).as("has number of elements").hasSize(1).as("and contains the following elements")
.containsExactly(expectedIdName).as("and NAMED filter query returns the same result")
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThat1TargetWithGivenNameOrDescAndDSIsInPending(final DistributionSet setA,
final List<TargetUpdateStatus> pending, final Target expected) {
final TargetIdName expectedIdName = convertToIdName(expected);
final String query = "updatestatus==pending and (assignedds.name==" + setA.getName() + " or installedds.name=="
+ setA.getName() + ") and (name==*targ-A* or description==*targ-A*)";
assertThat(targetManagement
.findTargetByFilters(pageReq, pending, "%targ-A%", setA.getId(), Boolean.FALSE, new String[0])
.getContent()).as("has number of elements").hasSize(1)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, "%targ-A%",
setA.getId(), Boolean.FALSE, new String[0])))
.as("and contains the following elements").containsExactly(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, "%targ-A%", setA.getId(), Boolean.FALSE,
new String[0])).as("has number of elements").hasSize(1).as("and contains the following elements")
.containsExactly(expectedIdName).as("and NAMED filter query returns the same result")
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThat3TargetsWithGivenDSAreInPending(final DistributionSet setA,
final List<TargetUpdateStatus> pending, final List<Target> expected) {
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
final String query = "updatestatus==pending and (assignedds.name==" + setA.getName() + " or installedds.name=="
+ setA.getName() + ")";
assertThat(targetManagement
.findTargetByFilters(pageReq, pending, null, setA.getId(), Boolean.FALSE, new String[0]).getContent())
.as("has number of elements").hasSize(3).as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null, setA.getId(),
Boolean.FALSE, new String[0])))
.as("and contains the following elements").containsAll(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, setA.getId(), Boolean.FALSE,
new String[0])).as("has number of elements").hasSize(3).as("and contains the following elements")
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThat3TargetsAreInStatusPending(final List<TargetUpdateStatus> pending,
final List<Target> expected) {
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
final String query = "updatestatus==pending";
assertThat(targetManagement.findTargetByFilters(pageReq, pending, null, null, Boolean.FALSE, new String[0])
.getContent()).as("has number of elements").hasSize(3)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null, null,
Boolean.FALSE, new String[0])))
.as("and contains the following elements").containsAll(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(
targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, null, Boolean.FALSE, new String[0]))
.as("has number of elements").hasSize(3).as("and contains the following elements")
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThat99TargetsWithGivenNameOrDescAndTagAreInStatusUnknown(final TargetTag targTagW,
final List<TargetUpdateStatus> unknown, final List<Target> expected) {
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
final String query = "updatestatus==unknown and (name==*targ-B* or description==*targ-B*) and tag=="
+ targTagW.getName();
assertThat(targetManagement
.findTargetByFilters(pageReq, unknown, "%targ-B%", null, Boolean.FALSE, targTagW.getName())
.getContent()).as("has number of elements").hasSize(99)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(unknown, "%targ-B%", null,
Boolean.FALSE, targTagW.getName())))
.as("and contains the following elements").containsAll(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, "%targ-B%", null, Boolean.FALSE,
targTagW.getName())).as("has number of elements").hasSize(99).as("and contains the following elements")
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThat99TargetsWithNameOrDescriptionAreInGivenStatus(final List<TargetUpdateStatus> unknown,
final List<Target> expected) {
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
final String query = "updatestatus==unknown and (name==*targ-A* or description==*targ-A*)";
assertThat(targetManagement
.findTargetByFilters(pageReq, unknown, "%targ-A%", null, Boolean.FALSE, new String[0]).getContent())
.as("has number of elements").hasSize(99).as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(unknown, "%targ-A%", null,
Boolean.FALSE, new String[0])))
.as("and contains the following elements").containsAll(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, "%targ-A%", null, Boolean.FALSE,
new String[0])).as("has number of elements").hasSize(99).as("and contains the following elements")
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
new JpaTargetFilterQuery("test", query)));
}
@Step
private void verfyThat0TargetsAreInStatusUnknownAndHaveDSAssigned(final DistributionSet setA,
final List<TargetUpdateStatus> unknown) {
final String query = "updatestatus==unknown and (assignedds.name==" + setA.getName() + " or installedds.name=="
+ setA.getName() + ")";
assertThat(targetManagement
.findTargetByFilters(pageReq, unknown, null, setA.getId(), Boolean.FALSE, new String[0]).getContent())
.as("has number of elements").hasSize(0).as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(unknown, null, setA.getId(),
Boolean.FALSE, new String[0])))
.as("and filter query returns the same result")
.hasSize(targetManagement.findTargetsAll(query, pageReq).getContent().size())
.as("and NAMED filter query returns the same result").hasSize(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent().size());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, null, setA.getId(), Boolean.FALSE,
new String[0])).as("has number of elements").hasSize(0)
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThat198TargetsAreInStatusUnknownAndHaveGivenTags(final TargetTag targTagY,
final TargetTag targTagW, final List<TargetUpdateStatus> unknown, final List<Target> expected) {
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
final String query = "updatestatus==unknown and (tag==" + targTagY.getName() + " or tag==" + targTagW.getName()
+ ")";
assertThat(targetManagement.findTargetByFilters(pageReq, unknown, null, null, Boolean.FALSE, targTagY.getName(),
targTagW.getName()).getContent()).as("has number of elements").hasSize(198)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(unknown, null, null,
Boolean.FALSE, targTagY.getName(), targTagW.getName())))
.as("and contains the following elements").containsAll(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, null, null, Boolean.FALSE,
targTagY.getName(), targTagW.getName())).as("has number of elements").hasSize(198)
.as("and contains the following elements").containsAll(expectedIdNames)
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThat397TargetsAreInStatusUnknown(final List<TargetUpdateStatus> unknown,
final List<Target> expected) {
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
final String query = "updatestatus==unknown";
assertThat(targetManagement.findTargetByFilters(pageReq, unknown, null, null, Boolean.FALSE, new String[0])
.getContent()).as("has number of elements").hasSize(397)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(unknown, null, null,
Boolean.FALSE, new String[0])))
.as("and contains the following elements").containsAll(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(
targetManagement.findAllTargetIdsByFilters(pageReq, unknown, null, null, Boolean.FALSE, new String[0]))
.as("has number of elements").hasSize(397).as("and contains the following elements")
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThat1TargetWithDescOrNameHasDS(final DistributionSet setA, final Target expected) {
final TargetIdName expectedIdName = convertToIdName(expected);
final String query = "(name==*targ-A* or description==*targ-A*) and (assignedds.name==" + setA.getName()
+ " or installedds.name==" + setA.getName() + ")";
assertThat(targetManagement
.findTargetByFilters(pageReq, null, "%targ-A%", setA.getId(), Boolean.FALSE, new String[0])
.getContent()).as("has number of elements").hasSize(1)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, "%targ-A%",
setA.getId(), Boolean.FALSE, new String[0])))
.as("and contains the following elements").containsExactly(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, "%targ-A%", setA.getId(), Boolean.FALSE,
new String[0])).as("has number of elements").hasSize(1).as("and contains the following elements")
.containsExactly(expectedIdName).as("and NAMED filter query returns the same result")
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThat3TargetsHaveDSAssigned(final DistributionSet setA, final List<Target> expected) {
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
final String query = "assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName();
assertThat(targetManagement.findTargetByFilters(pageReq, null, null, setA.getId(), Boolean.FALSE, new String[0])
.getContent()).as("has number of elements").hasSize(3)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, null, setA.getId(),
Boolean.FALSE, new String[0])))
.as("and contains the following elements").containsAll(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, null, setA.getId(), Boolean.FALSE,
new String[0])).as("has number of elements").hasSize(3).as("and contains the following elements")
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThat0TargetsWithNameOrdescAndDSHaveTag(final TargetTag targTagX, final DistributionSet setA) {
final String query = "(name==*targ-C* or description==*targ-C*) and tag==" + targTagX.getName()
+ " and (assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName() + ")";
assertThat(targetManagement
.findTargetByFilters(pageReq, null, "%targ-C%", setA.getId(), Boolean.FALSE, targTagX.getName())
.getContent()).as("has number of elements").hasSize(0)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, "%targ-C%",
setA.getId(), Boolean.FALSE, targTagX.getName())))
.as("and filter query returns the same result")
.hasSize(targetManagement.findTargetsAll(query, pageReq).getContent().size())
.as("and NAMED filter query returns the same result").hasSize(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent().size());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, "%targ-C%", setA.getId(), Boolean.FALSE,
targTagX.getName())).as("has number of elements").hasSize(0)
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThat0TargetsWithTagAndDescOrNameHasDS(final TargetTag targTagW, final DistributionSet setA) {
final String query = "(name==*targ-A* or description==*targ-A*) and tag==" + targTagW.getName()
+ " and (assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName() + ")";
assertThat(targetManagement
.findTargetByFilters(pageReq, null, "%targ-A%", setA.getId(), Boolean.FALSE, targTagW.getName())
.getContent()).as("has number of elements").hasSize(0)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, "%targ-A%",
setA.getId(), Boolean.FALSE, targTagW.getName())))
.as("and filter query returns the same result")
.hasSize(targetManagement.findTargetsAll(query, pageReq).getContent().size())
.as("and NAMED filter query returns the same result").hasSize(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent().size());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, "%targ-A%", setA.getId(), Boolean.FALSE,
targTagW.getName())).as("has number of elements").hasSize(0)
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThat1TargetHasTagHasDescOrNameAndDs(final TargetTag targTagW, final DistributionSet setA,
final Target expected) {
final TargetIdName expectedIdName = convertToIdName(expected);
final String query = "(name==*targ-c* or description==*targ-C*) and tag==" + targTagW.getName()
+ " and (assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName() + ")";
assertThat(targetManagement
.findTargetByFilters(pageReq, null, "%targ-C%", setA.getId(), Boolean.FALSE, targTagW.getName())
.getContent()).as("has number of elements").hasSize(1)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, "%targ-C%",
setA.getId(), Boolean.FALSE, targTagW.getName())))
.as("and contains the following elements").containsExactly(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, "%targ-C%", setA.getId(), Boolean.FALSE,
targTagW.getName())).as("has number of elements").hasSize(1).as("and contains the following elements")
.containsExactly(expectedIdName).as("and NAMED filter query returns the same result")
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThat100TargetsContainsGivenTextAndHaveTagAssigned(final TargetTag targTagY,
final TargetTag targTagW, final List<Target> expected) {
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
final String query = "(name==*targ-B* or description==*targ-B*) and (tag==" + targTagY.getName() + " or tag=="
+ targTagW.getName() + ")";
assertThat(targetManagement.findTargetByFilters(pageReq, null, "%targ-B%", null, Boolean.FALSE,
targTagY.getName(), targTagW.getName()).getContent()).as("has number of elements").hasSize(100)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, "%targ-B%", null,
Boolean.FALSE, targTagY.getName(), targTagW.getName())))
.as("and contains the following elements").containsAll(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, "%targ-B%", null, Boolean.FALSE,
targTagY.getName(), targTagW.getName())).as("has number of elements").hasSize(100)
.as("and contains the following elements").containsAll(expectedIdNames)
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query)));
}
@SafeVarargs
private final List<Target> concat(final List<Target>... targets) {
final List<Target> result = new ArrayList<>();
Arrays.asList(targets).forEach(result::addAll);
return result;
}
@Step
private void verifyThat200TargetsHaveTagD(final TargetTag targTagD, final List<Target> expected) {
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
final String query = "tag==" + targTagD.getName();
assertThat(targetManagement.findTargetByFilters(pageReq, null, null, null, Boolean.FALSE, targTagD.getName())
.getContent()).as("Expected number of results is").hasSize(200)
.as("and is expected number of results is equal to ")
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, null, null,
Boolean.FALSE, targTagD.getName())))
.as("and contains the following elements").containsAll(expected)
.as("and filter query returns the same result")
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
.as("and NAMED filter query returns the same result").containsAll(targetManagement
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, null, null, Boolean.FALSE,
targTagD.getName())).as("has number of elements").hasSize(200).as("and contains the following elements")
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
new JpaTargetFilterQuery("test", query)));
}
@Step
private void verifyThatRepositoryContains400Targets() {
assertThat(targetManagement.findTargetByFilters(pageReq, null, null, null, null, new String[0]).getContent())
.as("Overall we expect that many targets in the repository").hasSize(400)
.as("which is also reflected by repository count")
.hasSize(Ints.saturatedCast(targetManagement.countTargetsAll()))
.as("which is also reflected by call without specification")
.containsAll(targetManagement.findTargetsAll(pageReq).getContent());
}
@Test
@Description("Tests the correct order of targets based on selected distribution set. The system expects to have an order based on installed, assigned DS.")
public void targetSearchWithVariousFilterCombinationsAndOrderByDistributionSet() {
final List<Target> notAssigned = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(3, "not", "first description"));
List<Target> targAssigned = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(3, "assigned", "first description"));
List<Target> targInstalled = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(3, "installed", "first description"));
final DistributionSet ds = TestDataUtil.generateDistributionSet("a", softwareManagement,
distributionSetManagement);
targAssigned = deploymentManagement.assignDistributionSet(ds, targAssigned).getAssignedEntity();
targInstalled = deploymentManagement.assignDistributionSet(ds, targInstalled).getAssignedEntity();
targInstalled = sendUpdateActionStatusToTargets(ds, targInstalled, Status.FINISHED, "installed");
final Slice<Target> result = targetManagement.findTargetsAllOrderByLinkedDistributionSet(pageReq, ds.getId(),
null, null, null, Boolean.FALSE, new String[0]);
final Comparator<TenantAwareBaseEntity> byId = (e1, e2) -> Long.compare(e2.getId(), e1.getId());
assertThat(result.getNumberOfElements()).isEqualTo(9);
final List<Target> expected = new ArrayList<>();
Collections.sort(targInstalled, byId);
Collections.sort(targAssigned, byId);
Collections.sort(notAssigned, byId);
expected.addAll(targInstalled);
expected.addAll(targAssigned);
expected.addAll(notAssigned);
assertThat(result.getContent()).containsExactly(expected.toArray(new Target[0]));
}
@Test
@Description("Verfies that targets with given assigned DS are returned from repository.")
public void findTargetByAssignedDistributionSet() {
final DistributionSet assignedSet = TestDataUtil.generateDistributionSet("", softwareManagement,
distributionSetManagement);
targetManagement.createTargets(TestDataUtil.generateTargets(10, "unassigned"));
List<Target> assignedtargets = targetManagement.createTargets(TestDataUtil.generateTargets(10, "assigned"));
deploymentManagement.assignDistributionSet(assignedSet, assignedtargets);
// get final updated version of targets
assignedtargets = targetManagement.findTargetByControllerID(
assignedtargets.stream().map(target -> target.getControllerId()).collect(Collectors.toList()));
assertThat(targetManagement.findTargetByAssignedDistributionSet(assignedSet.getId(), pageReq))
.as("Contains the assigned targets").containsAll(assignedtargets)
.as("and that means the following expected amount").hasSize(10);
}
@Test
@Description("Verfies that targets with given installed DS are returned from repository.")
public void findTargetByInstalledDistributionSet() {
final DistributionSet assignedSet = TestDataUtil.generateDistributionSet("", softwareManagement,
distributionSetManagement);
final DistributionSet installedSet = TestDataUtil.generateDistributionSet("another", softwareManagement,
distributionSetManagement);
targetManagement.createTargets(TestDataUtil.generateTargets(10, "unassigned"));
List<Target> installedtargets = targetManagement.createTargets(TestDataUtil.generateTargets(10, "assigned"));
// set on installed and assign another one
deploymentManagement.assignDistributionSet(installedSet, installedtargets).getActions().forEach(actionId -> {
final Action action = deploymentManagement.findActionWithDetails(actionId);
action.setStatus(Status.FINISHED);
controllerManagament.addUpdateActionStatus(
new JpaActionStatus((JpaAction) action, Status.FINISHED, System.currentTimeMillis(), "message"));
});
deploymentManagement.assignDistributionSet(assignedSet, installedtargets);
// get final updated version of targets
installedtargets = targetManagement.findTargetByControllerID(
installedtargets.stream().map(target -> target.getControllerId()).collect(Collectors.toList()));
assertThat(targetManagement.findTargetByInstalledDistributionSet(installedSet.getId(), pageReq))
.as("Contains the assigned targets").containsAll(installedtargets)
.as("and that means the following expected amount").hasSize(10);
}
private List<Target> sendUpdateActionStatusToTargets(final DistributionSet dsA, final Iterable<Target> targs,
final Status status, final String... msgs) {
final List<Target> result = new ArrayList<Target>();
for (final Target t : targs) {
final List<Action> findByTarget = actionRepository.findByTarget((JpaTarget) t);
for (final Action action : findByTarget) {
result.add(sendUpdateActionStatusToTarget(status, action, t, msgs));
}
}
return result;
}
private Target sendUpdateActionStatusToTarget(final Status status, final Action updActA, final Target t,
final String... msgs) {
updActA.setStatus(status);
final ActionStatus statusMessages = new JpaActionStatus();
statusMessages.setAction(updActA);
statusMessages.setOccurredAt(System.currentTimeMillis());
statusMessages.setStatus(status);
for (final String msg : msgs) {
statusMessages.addMessage(msg);
}
controllerManagament.addUpdateActionStatus(statusMessages);
return targetManagement.findTargetByControllerID(t.getControllerId());
}
}

View File

@@ -0,0 +1,778 @@
/**
* 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;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;
import javax.persistence.Query;
import javax.validation.ConstraintViolationException;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.TestDataUtil;
import org.eclipse.hawkbit.WithSpringAuthorityRule;
import org.eclipse.hawkbit.WithUser;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.TenantNotExistException;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Tag;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetIdName;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.junit.Test;
import org.springframework.data.domain.PageRequest;
import com.google.common.collect.Iterables;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("Target Management")
public class TargetManagementTest extends AbstractIntegrationTest {
@Test
@Description("Ensures that retrieving the target security is only permitted with the necessary permissions.")
public void getTargetSecurityTokenOnlyWithCorrectPermission() throws Exception {
final Target createdTarget = targetManagement.createTarget(new JpaTarget("targetWithSecurityToken"));
// retrieve security token only with READ_TARGET_SEC_TOKEN permission
final String securityTokenWithReadPermission = securityRule.runAs(WithSpringAuthorityRule
.withUser("OnlyTargetReadPermission", false, SpPermission.READ_TARGET_SEC_TOKEN.toString()), () -> {
return createdTarget.getSecurityToken();
});
// retrieve security token as system code execution
final String securityTokenAsSystemCode = systemSecurityContext.runAsSystem(() -> {
return createdTarget.getSecurityToken();
});
// retrieve security token without any permissions
final String securityTokenWithoutPermission = securityRule
.runAs(WithSpringAuthorityRule.withUser("NoPermission", false), () -> {
return createdTarget.getSecurityToken();
});
assertThat(createdTarget.getSecurityToken()).isNotNull();
assertThat(securityTokenWithReadPermission).isNotNull();
assertThat(securityTokenAsSystemCode).isNotNull();
assertThat(securityTokenWithoutPermission).isNull();
}
@Test
@Description("Ensures that targets cannot be created e.g. in plug'n play scenarios when tenant does not exists.")
@WithUser(tenantId = "tenantWhichDoesNotExists", allSpPermissions = true, autoCreateTenant = false)
public void createTargetForTenantWhichDoesNotExistThrowsTenantNotExistException() {
try {
targetManagement.createTarget(new JpaTarget("targetId123"));
fail("should not be possible as the tenant does not exist");
} catch (final TenantNotExistException e) {
// ok
}
}
@Test
@Description("Verify that a target with empty controller id cannot be created")
public void createTargetWithNoControllerId() {
try {
targetManagement.createTarget(new JpaTarget(""));
fail("target with empty controller id should not be created");
} catch (final ConstraintViolationException e) {
// ok
}
try {
targetManagement.createTarget(new JpaTarget(null));
fail("target with empty controller id should not be created");
} catch (final ConstraintViolationException e) {
// ok
}
}
@Test
@Description("Ensures that targets can assigned and unassigned to a target tag. Not exists target will be ignored for the assignment.")
public void assignAndUnassignTargetsToTag() {
final List<String> assignTarget = new ArrayList<String>();
assignTarget.add(targetManagement.createTarget(new JpaTarget("targetId123")).getControllerId());
assignTarget.add(targetManagement.createTarget(new JpaTarget("targetId1234")).getControllerId());
assignTarget.add(targetManagement.createTarget(new JpaTarget("targetId1235")).getControllerId());
assignTarget.add(targetManagement.createTarget(new JpaTarget("targetId1236")).getControllerId());
assignTarget.add("NotExist");
final TargetTag targetTag = tagManagement.createTargetTag(new JpaTargetTag("Tag1"));
final List<Target> assignedTargets = targetManagement.assignTag(assignTarget, targetTag);
assertThat(assignedTargets.size()).as("Assigned targets are wrong").isEqualTo(4);
assignedTargets.forEach(target -> assertThat(target.getTags().size()).isEqualTo(1));
TargetTag findTargetTag = tagManagement.findTargetTag("Tag1");
assertThat(assignedTargets.size()).as("Assigned targets are wrong")
.isEqualTo(findTargetTag.getAssignedToTargets().size());
assertThat(targetManagement.unAssignTag("NotExist", findTargetTag)).as("Unassign target does not work")
.isNull();
final Target unAssignTarget = targetManagement.unAssignTag("targetId123", findTargetTag);
assertThat(unAssignTarget.getControllerId()).as("Controller id is wrong").isEqualTo("targetId123");
assertThat(unAssignTarget.getTags()).as("Tag size is wrong").isEmpty();
findTargetTag = tagManagement.findTargetTag("Tag1");
assertThat(findTargetTag.getAssignedToTargets()).as("Assigned targets are wrong").hasSize(3);
final List<Target> unAssignTargets = targetManagement.unAssignAllTargetsByTag(findTargetTag);
findTargetTag = tagManagement.findTargetTag("Tag1");
assertThat(findTargetTag.getAssignedToTargets()).as("Unassigned targets are wrong").isEmpty();
assertThat(unAssignTargets).as("Unassigned targets are wrong").hasSize(3);
unAssignTargets.forEach(target -> assertThat(target.getTags().size()).isEqualTo(0));
}
@Test
@Description("Ensures that targets can deleted e.g. test all cascades")
public void deleteAndCreateTargets() {
Target target = targetManagement.createTarget(new JpaTarget("targetId123"));
assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(1);
targetManagement.deleteTargets(target.getId());
assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(0);
target = createTargetWithAttributes("4711");
assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(1);
targetManagement.deleteTargets(target.getId());
assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(0);
final List<Long> targets = new ArrayList<Long>();
for (int i = 0; i < 5; i++) {
target = targetManagement.createTarget(new JpaTarget("" + i));
targets.add(target.getId());
targets.add(createTargetWithAttributes("" + (i * i + 1000)).getId());
}
assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(10);
targetManagement.deleteTargets(targets.toArray(new Long[targets.size()]));
assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(0);
}
private Target createTargetWithAttributes(final String controllerId) {
Target target = new JpaTarget(controllerId);
final Map<String, String> testData = new HashMap<>();
testData.put("test1", "testdata1");
target = targetManagement.createTarget(target);
target = controllerManagament.updateControllerAttributes(controllerId, testData);
target = targetManagement.findTargetByControllerIDWithDetails(controllerId);
assertThat(target.getTargetInfo().getControllerAttributes()).as("Controller Attributes are wrong")
.isEqualTo(testData);
return target;
}
@Test
@Description("Finds a target by given ID and checks if all data is in the reponse (including the data defined as lazy).")
public void findTargetByControllerIDWithDetails() {
final DistributionSet set = TestDataUtil.generateDistributionSet("test", softwareManagement,
distributionSetManagement);
final DistributionSet set2 = TestDataUtil.generateDistributionSet("test2", softwareManagement,
distributionSetManagement);
assertThat(targetManagement.countTargetByAssignedDistributionSet(set.getId())).as("Target count is wrong")
.isEqualTo(0);
assertThat(targetManagement.countTargetByInstalledDistributionSet(set.getId())).as("Target count is wrong")
.isEqualTo(0);
assertThat(targetManagement.countTargetByAssignedDistributionSet(set2.getId())).as("Target count is wrong")
.isEqualTo(0);
assertThat(targetManagement.countTargetByInstalledDistributionSet(set2.getId())).as("Target count is wrong")
.isEqualTo(0);
Target target = createTargetWithAttributes("4711");
final long current = System.currentTimeMillis();
controllerManagament.updateLastTargetQuery("4711", null);
final DistributionSetAssignmentResult result = deploymentManagement.assignDistributionSet(set.getId(), "4711");
final JpaAction action = (JpaAction) deploymentManagement.findActionWithDetails(result.getActions().get(0));
action.setStatus(Status.FINISHED);
controllerManagament.addUpdateActionStatus(
new JpaActionStatus(action, Status.FINISHED, System.currentTimeMillis(), "message"));
deploymentManagement.assignDistributionSet(set2.getId(), "4711");
target = targetManagement.findTargetByControllerIDWithDetails("4711");
// read data
assertThat(targetManagement.countTargetByAssignedDistributionSet(set.getId())).as("Target count is wrong")
.isEqualTo(0);
assertThat(targetManagement.countTargetByInstalledDistributionSet(set.getId())).as("Target count is wrong")
.isEqualTo(1);
assertThat(targetManagement.countTargetByAssignedDistributionSet(set2.getId())).as("Target count is wrong")
.isEqualTo(1);
assertThat(targetManagement.countTargetByInstalledDistributionSet(set2.getId())).as("Target count is wrong")
.isEqualTo(0);
assertThat(target.getTargetInfo().getLastTargetQuery()).as("Target query is not work")
.isGreaterThanOrEqualTo(current);
assertThat(target.getAssignedDistributionSet()).as("Assigned ds size is wrong").isEqualTo(set2);
assertThat(target.getTargetInfo().getInstalledDistributionSet().getId()).as("Installed ds is wrong")
.isEqualTo(set.getId());
}
@Test
@Description("Ensures that repositoy returns null if given controller ID does not exist without exception.")
public void findTargetByControllerIDWithDetailsReturnsNullForNonexisting() {
assertThat(targetManagement.findTargetByControllerIDWithDetails("dsfsdfsdfsd")).as("Expected as").isNull();
}
@Test
@Description("Checks if the EntityAlreadyExistsException is thrown if the targets with the same controller ID are created twice.")
public void createMultipleTargetsDuplicate() {
final List<Target> targets = TestDataUtil.buildTargetFixtures(5, "mySimpleTargs", "my simple targets");
targetManagement.createTargets(targets);
try {
targetManagement.createTargets(targets);
fail("Targets already exists");
} catch (final EntityAlreadyExistsException e) {
}
}
@Test
@Description("Checks if the EntityAlreadyExistsException is thrown if a single target with the same controller ID are created twice.")
public void createTargetDuplicate() {
targetManagement.createTarget(new JpaTarget("4711"));
try {
targetManagement.createTarget(new JpaTarget("4711"));
fail("Target already exists");
} catch (final EntityAlreadyExistsException e) {
}
}
/**
* verifies, that all {@link TargetTag} of parameter. NOTE: it's accepted
* that the target have additional tags assigned to them which are not
* contained within parameter tags.
*
* @param strict
* if true, the given targets MUST contain EXACTLY ALL given
* tags, AND NO OTHERS. If false, the given targets MUST contain
* ALL given tags, BUT MAY CONTAIN FURTHER ONE
* @param targets
* targets to be verified
* @param tags
* are contained within tags of all targets.
* @param tags
* to be found in the tags of the targets
*/
private void checkTargetHasTags(final boolean strict, final Iterable<Target> targets, final TargetTag... tags) {
_target: for (final Target tl : targets) {
final Target t = targetManagement.findTargetByControllerID(tl.getControllerId());
for (final Tag tt : t.getTags()) {
for (final Tag tag : tags) {
if (tag.getName().equals(tt.getName())) {
continue _target;
}
}
if (strict) {
fail("Target does not contain all tags");
}
}
fail("Target does not contain any tags or the expected tag was not found");
}
}
private void checkTargetHasNotTags(final Iterable<Target> targets, final TargetTag... tags) {
for (final Target tl : targets) {
final Target t = targetManagement.findTargetByControllerID(tl.getControllerId());
for (final Tag tag : tags) {
for (final Tag tt : t.getTags()) {
if (tag.getName().equals(tt.getName())) {
fail("Target should have no tags");
}
}
}
}
}
@Test
@WithUser(allSpPermissions = true)
@Description("Creates and updates a target and verifies the changes in the repository.")
public void singleTargetIsInsertedIntoRepo() throws Exception {
final String myCtrlID = "myCtrlID";
final Target target = TestDataUtil.buildTargetFixture(myCtrlID, "the description!");
Target savedTarget = targetManagement.createTarget(target);
assertNotNull("The target should not be null", savedTarget);
final Long createdAt = savedTarget.getCreatedAt();
Long modifiedAt = savedTarget.getLastModifiedAt();
assertThat(createdAt).as("CreatedAt compared with modifiedAt").isEqualTo(modifiedAt);
assertNotNull("The createdAt attribut of the target should no be null", savedTarget.getCreatedAt());
assertNotNull("The lastModifiedAt attribut of the target should no be null", savedTarget.getLastModifiedAt());
assertThat(target).as("Target compared with saved target").isEqualTo(savedTarget);
savedTarget.setDescription("changed description");
Thread.sleep(1);
savedTarget = targetManagement.updateTarget(savedTarget);
assertNotNull("The lastModifiedAt attribute of the target should not be null", savedTarget.getLastModifiedAt());
assertThat(createdAt).as("CreatedAt compared with saved modifiedAt")
.isNotEqualTo(savedTarget.getLastModifiedAt());
assertThat(modifiedAt).as("ModifiedAt compared with saved modifiedAt")
.isNotEqualTo(savedTarget.getLastModifiedAt());
modifiedAt = savedTarget.getLastModifiedAt();
final Target foundTarget = targetManagement.findTargetByControllerID(savedTarget.getControllerId());
assertNotNull("The target should not be null", foundTarget);
assertThat(myCtrlID).as("ControllerId compared with saved controllerId")
.isEqualTo(foundTarget.getControllerId());
assertThat(savedTarget).as("Target compared with saved target").isEqualTo(foundTarget);
assertThat(createdAt).as("CreatedAt compared with saved createdAt").isEqualTo(foundTarget.getCreatedAt());
assertThat(modifiedAt).as("LastModifiedAt compared with saved lastModifiedAt")
.isEqualTo(foundTarget.getLastModifiedAt());
}
@Test
@WithUser(allSpPermissions = true)
@Description("Create multiple tragets as bulk operation and delete them in bulk.")
public void bulkTargetCreationAndDelete() throws Exception {
final String myCtrlID = "myCtrlID";
final List<Target> firstList = TestDataUtil.buildTargetFixtures(100, myCtrlID, "first description");
final Target extra = TestDataUtil.buildTargetFixture("myCtrlID-00081XX", "first description");
List<Target> firstSaved = targetManagement.createTargets(firstList);
final Target savedExtra = targetManagement.createTarget(extra);
final Iterable<JpaTarget> allFound = targetRepository.findAll();
assertThat(Long.valueOf(firstList.size())).as("List size of targets")
.isEqualTo(firstSaved.spliterator().getExactSizeIfKnown());
assertThat(Long.valueOf(firstList.size() + 1)).as("LastModifiedAt compared with saved lastModifiedAt")
.isEqualTo(allFound.spliterator().getExactSizeIfKnown());
// change the objects and save to again to trigger a change on
// lastModifiedAt
firstSaved.forEach(t -> t.setName(t.getName().concat("\tchanged")));
firstSaved = targetManagement.updateTargets(firstSaved);
// verify that all entries are found
_founds: for (final Target foundTarget : allFound) {
for (final Target changedTarget : firstSaved) {
if (changedTarget.getControllerId().equals(foundTarget.getControllerId())) {
assertThat(changedTarget.getDescription())
.as("Description of changed target compared with description saved target")
.isEqualTo(foundTarget.getDescription());
assertThat(changedTarget.getName()).as("Name of changed target starts with name of saved target")
.startsWith(foundTarget.getName());
assertThat(changedTarget.getName()).as("Name of changed target ends with 'changed'")
.endsWith("changed");
assertThat(changedTarget.getCreatedAt()).as("CreatedAt compared with saved createdAt")
.isEqualTo(foundTarget.getCreatedAt());
assertThat(changedTarget.getLastModifiedAt()).as("LastModifiedAt compared with saved createdAt")
.isNotEqualTo(changedTarget.getCreatedAt());
continue _founds;
}
}
if (!foundTarget.getControllerId().equals(savedExtra.getControllerId())) {
fail("The controllerId of the found target is not equal to the controllerId of the saved target");
}
}
targetManagement.deleteTargets(savedExtra.getId());
final int nr2Del = 50;
int i = nr2Del;
final Long[] deletedTargetIDs = new Long[nr2Del];
final Target[] deletedTargets = new Target[nr2Del];
final Iterator<Target> it = firstSaved.iterator();
while (nr2Del > 0 && it.hasNext() && i > 0) {
final Target pt = it.next();
deletedTargetIDs[i - 1] = pt.getId();
deletedTargets[i - 1] = pt;
i--;
}
targetManagement.deleteTargets(deletedTargetIDs);
final List<Target> found = targetManagement.findTargetsAll(new PageRequest(0, 200)).getContent();
assertThat(firstSaved.spliterator().getExactSizeIfKnown() - nr2Del).as("Size of splited list")
.isEqualTo(found.spliterator().getExactSizeIfKnown());
assertThat(found).as("Not all undeleted found").doesNotContain(deletedTargets);
}
@Test
@Description("Stores target attributes and verfies existence in the repository.")
public void savingTargetControllerAttributes() {
Iterable<Target> ts = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(100, "myCtrlID", "first description"));
final Map<String, String> attribs = new HashMap<>();
attribs.put("a.b.c", "abc");
attribs.put("x.y.z", "");
attribs.put("1.2.3", "123");
attribs.put("1.2.3.4", "1234");
attribs.put("1.2.3.4.5", "12345");
final Set<String> attribs2Del = new HashSet<>();
attribs2Del.add("x.y.z");
attribs2Del.add("1.2.3");
for (final Target t : ts) {
JpaTargetInfo targetInfo = (JpaTargetInfo) t.getTargetInfo();
targetInfo.setNew(false);
for (final Entry<String, String> attrib : attribs.entrySet()) {
final String key = attrib.getKey();
final String value = String.format("%s-%s", attrib.getValue(), t.getControllerId());
targetInfo.getControllerAttributes().put(key, value);
}
targetInfo = targetInfoRepository.save(targetInfo);
}
final Query qry = entityManager.createNativeQuery("select * from sp_target_attributes ta");
final List<?> result = qry.getResultList();
assertThat(attribs.size() * ts.spliterator().getExactSizeIfKnown()).as("Amount of all target attributes")
.isEqualTo(result.size());
for (final Target myT : ts) {
final Target t = targetManagement.findTargetByControllerIDWithDetails(myT.getControllerId());
assertThat(attribs.size()).as("Amount of target attributes per target")
.isEqualTo(t.getTargetInfo().getControllerAttributes().size());
for (final Entry<String, String> ca : t.getTargetInfo().getControllerAttributes().entrySet()) {
assertTrue("Attributes list does not contain target attribute key", attribs.containsKey(ca.getKey()));
// has the same value: see string concatenation above
// assertThat(String.format("%s-%s",
// attribs.get(ca.getKey()))).as("Value of string
// concatenation")
// .isEqualTo(ca.getValue());
assertEquals("The value of the string concatenation is not equal to the value of the target attributes",
String.format("%s-%s", attribs.get(ca.getKey()), t.getControllerId()), ca.getValue());
}
}
ts = targetManagement.findTargetsAll(new PageRequest(0, 100)).getContent();
final Iterator<Target> tsIt = ts.iterator();
// all attributs of the target are deleted
final Target[] ts2DelAllAttribs = new Target[] { tsIt.next(), tsIt.next(), tsIt.next() };
// a few attributs are deleted
final Target[] ts2DelAttribs = new Target[] { tsIt.next(), tsIt.next() };
// perform the deletion operations accordingly
for (final Target ta : ts2DelAllAttribs) {
final Target t = targetManagement.findTargetByControllerIDWithDetails(ta.getControllerId());
final JpaTargetInfo targetStatus = (JpaTargetInfo) t.getTargetInfo();
targetStatus.getControllerAttributes().clear();
targetInfoRepository.save(targetStatus);
}
for (final Target ta : ts2DelAttribs) {
final Target t = targetManagement.findTargetByControllerIDWithDetails(ta.getControllerId());
final JpaTargetInfo targetStatus = (JpaTargetInfo) t.getTargetInfo();
for (final String attribKey : attribs2Del) {
targetStatus.getControllerAttributes().remove(attribKey);
}
targetInfoRepository.save(targetStatus);
}
// only the number of the remaining targets and controller attributes
// are checked
final Iterable<JpaTarget> restTS = targetRepository.findAll();
restTarget_: for (final Target targetl : restTS) {
final Target target = targetManagement.findTargetByControllerIDWithDetails(targetl.getControllerId());
// verify that all members of the list ts2DelAllAttribs don't have
// any attributes
for (final Target tNoAttribl : ts2DelAllAttribs) {
final Target tNoAttrib = targetManagement.findTargetByControllerID(tNoAttribl.getControllerId());
if (tNoAttrib.getControllerId().equals(target.getControllerId())) {
assertThat(target.getTargetInfo().getControllerAttributes())
.as("Controller attributes should be empty").isEmpty();
continue restTarget_;
}
}
// verify that that the attribute list of all members of the list
// ts2DelAttribs don't have
// attributes which have been deleted
for (final Target tNoAttribl : ts2DelAttribs) {
final Target tNoAttrib = targetManagement.findTargetByControllerID(tNoAttribl.getControllerId());
if (tNoAttrib.getControllerId().equals(target.getControllerId())) {
assertThat(target.getTargetInfo().getControllerAttributes().keySet().toArray())
.as("Controller attributes are wrong").doesNotContain(attribs2Del.toArray());
continue restTarget_;
}
}
}
}
@Test
@Description("Tests the assigment of tags to the a single target.")
public void targetTagAssignment() {
Target t1 = TestDataUtil.buildTargetFixture("id-1", "blablub");
final int noT2Tags = 4;
final int noT1Tags = 3;
final List<TargetTag> t1Tags = tagManagement
.createTargetTags(TestDataUtil.buildTargetTagFixtures(noT1Tags, "tag1"));
t1.getTags().addAll(t1Tags);
t1 = targetManagement.createTarget(t1);
Target t2 = TestDataUtil.buildTargetFixture("id-2", "blablub");
final List<TargetTag> t2Tags = tagManagement
.createTargetTags(TestDataUtil.buildTargetTagFixtures(noT2Tags, "tag2"));
t2.getTags().addAll(t2Tags);
t2 = targetManagement.createTarget(t2);
t1 = targetManagement.findTargetByControllerID(t1.getControllerId());
assertThat(t1.getTags()).as("Tag size is wrong").hasSize(noT1Tags).containsAll(t1Tags);
assertThat(t1.getTags()).as("Tag size is wrong").hasSize(noT1Tags)
.doesNotContain(Iterables.toArray(t2Tags, TargetTag.class));
t2 = targetManagement.findTargetByControllerID(t2.getControllerId());
assertThat(t2.getTags()).as("Tag size is wrong").hasSize(noT2Tags).containsAll(t2Tags);
assertThat(t2.getTags()).as("Tag size is wrong").hasSize(noT2Tags)
.doesNotContain(Iterables.toArray(t1Tags, TargetTag.class));
}
@Test
@Description("Tests the assigment of tags to multiple targets.")
public void targetTagBulkAssignments() {
final List<Target> tagATargets = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(10, "tagATargets", "first description"));
final List<Target> tagBTargets = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(10, "tagBTargets", "first description"));
final List<Target> tagCTargets = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(10, "tagCTargets", "first description"));
final List<Target> tagABTargets = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(10, "tagABTargets", "first description"));
final List<Target> tagABCTargets = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(10, "tagABCTargets", "first description"));
final TargetTag tagA = tagManagement.createTargetTag(new JpaTargetTag("A"));
final TargetTag tagB = tagManagement.createTargetTag(new JpaTargetTag("B"));
final TargetTag tagC = tagManagement.createTargetTag(new JpaTargetTag("C"));
tagManagement.createTargetTag(new JpaTargetTag("X"));
// doing different assignments
targetManagement.toggleTagAssignment(tagATargets, tagA);
targetManagement.toggleTagAssignment(tagBTargets, tagB);
targetManagement.toggleTagAssignment(tagCTargets, tagC);
targetManagement.toggleTagAssignment(tagABTargets, tagA);
targetManagement.toggleTagAssignment(tagABTargets, tagB);
targetManagement.toggleTagAssignment(tagABCTargets, tagA);
targetManagement.toggleTagAssignment(tagABCTargets, tagB);
targetManagement.toggleTagAssignment(tagABCTargets, tagC);
assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "X"))
.as("Target count is wrong").isEqualTo(0);
// search for targets with tag tagA
final List<Target> targetWithTagA = new ArrayList<Target>();
final List<Target> targetWithTagB = new ArrayList<Target>();
final List<Target> targetWithTagC = new ArrayList<Target>();
// storing target lists to enable easy evaluation
Iterables.addAll(targetWithTagA, tagATargets);
Iterables.addAll(targetWithTagA, tagABTargets);
Iterables.addAll(targetWithTagA, tagABCTargets);
Iterables.addAll(targetWithTagB, tagBTargets);
Iterables.addAll(targetWithTagB, tagABTargets);
Iterables.addAll(targetWithTagB, tagABCTargets);
Iterables.addAll(targetWithTagC, tagCTargets);
Iterables.addAll(targetWithTagC, tagABCTargets);
// check the target lists as returned by assignTag
checkTargetHasTags(false, targetWithTagA, tagA);
checkTargetHasTags(false, targetWithTagB, tagB);
checkTargetHasTags(false, targetWithTagC, tagC);
checkTargetHasNotTags(tagATargets, tagB, tagC);
checkTargetHasNotTags(tagBTargets, tagA, tagC);
checkTargetHasNotTags(tagCTargets, tagA, tagB);
// check again target lists refreshed from DB
assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "A"))
.as("Target count is wrong").isEqualTo(targetWithTagA.size());
assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "B"))
.as("Target count is wrong").isEqualTo(targetWithTagB.size());
assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "C"))
.as("Target count is wrong").isEqualTo(targetWithTagC.size());
}
@Test
@Description("Tests the unassigment of tags to multiple targets.")
public void targetTagBulkUnassignments() {
final TargetTag targTagA = tagManagement.createTargetTag(new JpaTargetTag("Targ-A-Tag"));
final TargetTag targTagB = tagManagement.createTargetTag(new JpaTargetTag("Targ-B-Tag"));
final TargetTag targTagC = tagManagement.createTargetTag(new JpaTargetTag("Targ-C-Tag"));
final List<Target> targAs = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(25, "target-id-A", "first description"));
final List<Target> targBs = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(20, "target-id-B", "first description"));
final List<Target> targCs = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(15, "target-id-C", "first description"));
final List<Target> targABs = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(12, "target-id-AB", "first description"));
final List<Target> targACs = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(13, "target-id-AC", "first description"));
final List<Target> targBCs = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(7, "target-id-BC", "first description"));
final List<Target> targABCs = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(17, "target-id-ABC", "first description"));
targetManagement.toggleTagAssignment(targAs, targTagA);
targetManagement.toggleTagAssignment(targABs, targTagA);
targetManagement.toggleTagAssignment(targACs, targTagA);
targetManagement.toggleTagAssignment(targABCs, targTagA);
targetManagement.toggleTagAssignment(targBs, targTagB);
targetManagement.toggleTagAssignment(targABs, targTagB);
targetManagement.toggleTagAssignment(targBCs, targTagB);
targetManagement.toggleTagAssignment(targABCs, targTagB);
targetManagement.toggleTagAssignment(targCs, targTagC);
targetManagement.toggleTagAssignment(targACs, targTagC);
targetManagement.toggleTagAssignment(targBCs, targTagC);
targetManagement.toggleTagAssignment(targABCs, targTagC);
checkTargetHasTags(true, targAs, targTagA);
checkTargetHasTags(true, targBs, targTagB);
checkTargetHasTags(true, targABs, targTagA, targTagB);
checkTargetHasTags(true, targACs, targTagA, targTagC);
checkTargetHasTags(true, targBCs, targTagB, targTagC);
checkTargetHasTags(true, targABCs, targTagA, targTagB, targTagC);
targetManagement.toggleTagAssignment(targCs, targTagC);
targetManagement.toggleTagAssignment(targACs, targTagC);
targetManagement.toggleTagAssignment(targBCs, targTagC);
targetManagement.toggleTagAssignment(targABCs, targTagC);
checkTargetHasTags(true, targAs, targTagA);
checkTargetHasTags(true, targBs, targTagB);
checkTargetHasTags(true, targABs, targTagA, targTagB);
checkTargetHasTags(true, targBCs, targTagB);
checkTargetHasTags(true, targACs, targTagA);
checkTargetHasNotTags(targCs, targTagC);
checkTargetHasNotTags(targACs, targTagC);
checkTargetHasNotTags(targBCs, targTagC);
checkTargetHasNotTags(targABCs, targTagC);
}
@Test
@Description("Retrieves targets by ID with lazy loading of the tags. Checks the successfull load.")
public void findTargetsByControllerIDsWithTags() {
final TargetTag targTagA = tagManagement.createTargetTag(new JpaTargetTag("Targ-A-Tag"));
final List<Target> targAs = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(25, "target-id-A", "first description"));
targetManagement.toggleTagAssignment(targAs, targTagA);
assertThat(targetManagement.findTargetsByControllerIDsWithTags(
targAs.stream().map(target -> target.getControllerId()).collect(Collectors.toList())))
.as("Target count is wrong").hasSize(25);
// no lazy loading exception and tag correctly assigned
assertThat(targetManagement
.findTargetsByControllerIDsWithTags(
targAs.stream().map(target -> target.getControllerId()).collect(Collectors.toList()))
.stream().map(target -> target.getTags().contains(targTagA)).collect(Collectors.toList()))
.as("Tags not correctly assigned").containsOnly(true);
}
@Test
@Description("Test the optimized quere for retrieving all ID/name pairs of targets.")
public void findAllTargetIdNamePaiss() {
final List<Target> targAs = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(25, "target-id-A", "first description"));
final String[] createdTargetIds = targAs.stream().map(t -> t.getControllerId())
.toArray(size -> new String[size]);
final List<TargetIdName> findAllTargetIdNames = targetManagement.findAllTargetIds();
final List<String> findAllTargetIds = findAllTargetIdNames.stream().map(TargetIdName::getControllerId)
.collect(Collectors.toList());
assertThat(findAllTargetIds).as("Target list has wrong content").containsOnly(createdTargetIds);
}
@Test
@Description("Test that NO TAG functionality which gives all targets with no tag assigned.")
public void findTargetsWithNoTag() {
final TargetTag targTagA = tagManagement.createTargetTag(new JpaTargetTag("Targ-A-Tag"));
final List<Target> targAs = targetManagement
.createTargets(TestDataUtil.buildTargetFixtures(25, "target-id-A", "first description"));
targetManagement.toggleTagAssignment(targAs, targTagA);
targetManagement.createTargets(TestDataUtil.buildTargetFixtures(25, "target-id-B", "first description"));
final String[] tagNames = null;
final List<Target> targetsListWithNoTag = targetManagement
.findTargetByFilters(new PageRequest(0, 500), null, null, null, Boolean.TRUE, tagNames).getContent();
assertThat(50).as("Total targets").isEqualTo(targetManagement.findAllTargetIds().size());
assertThat(25).as("Targets with no tag").isEqualTo(targetsListWithNoTag.size());
}
@Test
@Description("Tests the a target can be read with only the read target permission")
public void targetCanBeReadWithOnlyReadTargetPermission() throws Exception {
final String knownTargetControllerId = "readTarget";
controllerManagament.findOrRegisterTargetIfItDoesNotexist(knownTargetControllerId, new URI("http://127.0.0.1"));
securityRule.runAs(WithSpringAuthorityRule.withUser("bumlux", "READ_TARGET"), () -> {
final Target findTargetByControllerID = targetManagement.findTargetByControllerID(knownTargetControllerId);
assertThat(findTargetByControllerID).isNotNull();
assertThat(findTargetByControllerID.getTargetInfo()).isNotNull();
assertThat(findTargetByControllerID.getTargetInfo().getPollStatus()).isNotNull();
return null;
});
}
}

View File

@@ -0,0 +1,256 @@
/**
* 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;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import java.time.Duration;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB;
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationValidatorException;
import org.junit.Assert;
import org.junit.Test;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("Tenant Configuration Management")
public class TenantConfigurationManagementTest extends AbstractIntegrationTestWithMongoDB {
@Test
@Description("Tests that tenant specific configuration can be persisted and in case the tenant does not have specific configuration the default from environment is used instead.")
public void storeTenantSpecificConfigurationAsString() {
final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME;
final String envPropertyDefault = environment.getProperty(configKey.getDefaultKeyName());
assertThat(envPropertyDefault).isNotNull();
// get the configuration from the system management
final TenantConfigurationValue<String> defaultConfigValue = tenantConfigurationManagement
.getConfigurationValue(configKey, String.class);
assertThat(defaultConfigValue.isGlobal()).isEqualTo(true);
assertThat(defaultConfigValue.getValue()).isEqualTo(envPropertyDefault);
// update the tenant specific configuration
final String newConfigurationValue = "thisIsAnotherTokenName";
assertThat(newConfigurationValue).isNotEqualTo(defaultConfigValue.getValue());
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, newConfigurationValue);
// verify that new configuration value is used
final TenantConfigurationValue<String> updatedConfigurationValue = tenantConfigurationManagement
.getConfigurationValue(configKey, String.class);
assertThat(updatedConfigurationValue.isGlobal()).isEqualTo(false);
assertThat(updatedConfigurationValue.getValue()).isEqualTo(newConfigurationValue);
// assertThat(tenantConfigurationManagement.getTenantConfigurations()).hasSize(1);
}
@Test
@Description("Tests that the tenant specific configuration can be updated")
public void updateTenantSpecifcConfiguration() {
final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME;
final String value1 = "firstValue";
final String value2 = "secondValue";
// add value first
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value1);
assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue())
.isEqualTo(value1);
// update to value second
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value2);
assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue())
.isEqualTo(value2);
}
@Test
@Description("Tests that the configuration value can be converted from String to Integer automatically")
public void storeAndUpdateTenantSpecificConfigurationAsBoolean() {
final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED;
final Boolean value1 = true;
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value1);
assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, Boolean.class).getValue())
.isEqualTo(value1);
final Boolean value2 = false;
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value2);
assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, Boolean.class).getValue())
.isEqualTo(value2);
}
@Test
@Description("Tests that the get configuration throws exception in case the value cannot be automatically converted from String to Boolean")
public void wrongTenantConfigurationValueTypeThrowsException() {
final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED;
final String value1 = "thisIsNotABoolean";
// add value as String
try {
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value1);
fail("should not have worked as string is not a boolean");
} catch (final TenantConfigurationValidatorException e) {
}
}
@Test
@Description("Tests that a deletion of a tenant specific configuration deletes it from the database.")
public void deleteConfigurationReturnNullConfiguration() {
final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY;
// gateway token does not have default value so no configuration value
// is should be available
final String defaultConfigValue = tenantConfigurationManagement.getConfigurationValue(configKey, String.class)
.getValue();
assertThat(defaultConfigValue).isNull();
// update the tenant specific configuration
final String newConfigurationValue = "thisIsAnotherValueForPolling";
assertThat(newConfigurationValue).isNotEqualTo(defaultConfigValue);
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, newConfigurationValue);
// verify that new configuration value is used
final String updatedConfigurationValue = tenantConfigurationManagement
.getConfigurationValue(configKey, String.class).getValue();
assertThat(updatedConfigurationValue).isEqualTo(newConfigurationValue);
// delete the tenant specific configuration
tenantConfigurationManagement.deleteConfiguration(configKey);
// ensure that now gateway token is set again, because is deleted and
// must be null now
assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue()).isNull();
}
@Test
@Description("Test that an Exception is thrown, when an integer is stored but a string expected.")
public void storesIntegerWhenStringIsExpected() {
final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME;
final Integer wrongDataype = 123;
try {
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, wrongDataype);
fail("should not have worked as integer is not a string");
} catch (final TenantConfigurationValidatorException e) {
}
}
@Test
@Description("Test that an Exception is thrown, when an integer is stored but a boolean expected.")
public void storesIntegerWhenBooleanIsExpected() {
final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED;
final Integer wrongDataype = 123;
try {
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, wrongDataype);
fail("should not have worked as integer is not a boolean");
} catch (final TenantConfigurationValidatorException e) {
}
}
@Test
@Description("Test that an Exception is thrown, when an integer is stored as PollingTime.")
public void storesIntegerWhenPollingIntervalIsExpected() {
final TenantConfigurationKey configKey = TenantConfigurationKey.POLLING_TIME_INTERVAL;
final Integer wrongDataype = 123;
try {
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, wrongDataype);
fail("should not have worked as integer is not a time field");
} catch (final TenantConfigurationValidatorException e) {
}
}
@Test
@Description("Test that an Exception is thrown, when an invalid formatted string is stored as PollingTime.")
public void storesWrongFormattedStringAsPollingInterval() {
final TenantConfigurationKey configKey = TenantConfigurationKey.POLLING_TIME_INTERVAL;
final String wrongFormatted = "wrongFormatted";
try {
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, wrongFormatted);
fail("should not have worked as string is not a time field");
} catch (final TenantConfigurationValidatorException e) {
}
}
@Test
@Description("Test that an Exception is thrown, when an invalid formatted string is stored as PollingTime.")
public void storesTooSmallDurationAsPollingInterval() {
final TenantConfigurationKey configKey = TenantConfigurationKey.POLLING_TIME_INTERVAL;
final String tooSmallDuration = DurationHelper
.durationToFormattedString(DurationHelper.getDurationByTimeValues(0, 0, 1));
try {
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, tooSmallDuration);
fail("should not have worked as string has an invalid format");
} catch (final TenantConfigurationValidatorException e) {
}
}
@Test
@Description("Stores a correct formatted PollignTime and reads it again.")
public void storesCorrectDurationAsPollingInterval() {
final TenantConfigurationKey configKey = TenantConfigurationKey.POLLING_TIME_INTERVAL;
final Duration duration = DurationHelper.getDurationByTimeValues(1, 2, 0);
assertThat(duration).isEqualTo(Duration.ofHours(1).plusMinutes(2));
tenantConfigurationManagement.addOrUpdateConfiguration(configKey,
DurationHelper.durationToFormattedString(duration));
final String storedDurationString = tenantConfigurationManagement.getConfigurationValue(configKey, String.class)
.getValue();
assertThat(duration).isEqualTo(DurationHelper.formattedStringToDuration(storedDurationString));
}
@Test
@Description("Request a config value in a wrong Value")
public void requestConfigValueWithWrongType() {
try {
tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL,
Object.class);
Assert.fail("");
} catch (final TenantConfigurationValidatorException e) {
}
}
@Test
@Description("Verifies that every TenenatConfiguraationKeyName exists only once")
public void verifyThatAllKeysAreDifferent() {
final Map<String, Void> keynames = new HashMap<String, Void>();
Arrays.stream(TenantConfigurationKey.values()).forEach(key -> {
if (keynames.containsKey(key.getKeyName())) {
throw new IllegalStateException("The key names are not unique");
}
keynames.put(key.getKeyName(), null);
});
}
@Test
@Description("Get TenantConfigurationKeyByName")
public void getTenantConfigurationKeyByName() {
final TenantConfigurationKey configKey = TenantConfigurationKey.POLLING_TIME_INTERVAL;
assertThat(TenantConfigurationKey.fromKeyName(configKey.getKeyName())).isEqualTo(configKey);
}
}

View File

@@ -0,0 +1,108 @@
/**
* 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.model;
import static org.fest.assertions.api.Assertions.assertThat;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
import org.junit.Test;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Unit Tests - Repository")
@Stories("Repository Model")
public class ModelEqualsHashcodeTest extends AbstractIntegrationTest {
@Test
@Description("Verfies that different objects even with identical primary key, version and tenant "
+ "return different hash codes.")
public void differentEntitiesReturnDifferentHashCodes() {
assertThat(new JpaAction().hashCode()).as("action should have different hashcode than action status")
.isNotEqualTo(new JpaActionStatus().hashCode());
assertThat(new JpaDistributionSet().hashCode())
.as("Distribution set should have different hashcode than software module")
.isNotEqualTo(new JpaSoftwareModule().hashCode());
assertThat(new JpaDistributionSet().hashCode())
.as("Distribution set should have different hashcode than action status")
.isNotEqualTo(new JpaActionStatus().hashCode());
assertThat(new JpaDistributionSetType().hashCode())
.as("Distribution set type should have different hashcode than action status")
.isNotEqualTo(new JpaActionStatus().hashCode());
}
@Test
@Description("Verfies that different object even with identical primary key, version and tenant "
+ "are not equal.")
public void differentEntitiesAreNotEqual() {
assertThat(new JpaAction().equals(new JpaActionStatus())).as("action equals action status").isFalse();
assertThat(new JpaDistributionSet().equals(new JpaSoftwareModule()))
.as("Distribution set equals software module").isFalse();
assertThat(new JpaDistributionSet().equals(new JpaActionStatus())).as("Distribution set equals action status")
.isFalse();
assertThat(new JpaDistributionSetType().equals(new JpaActionStatus()))
.as("Distribution set type equals action status").isFalse();
}
@Test
@Description("Verfies that updated entities are not equal.")
public void changedEntitiesAreNotEqual() {
final SoftwareModuleType type = softwareManagement
.createSoftwareModuleType(new JpaSoftwareModuleType("test", "test", "test", 1));
assertThat(type).as("persited entity is not equal to regular object")
.isNotEqualTo(new JpaSoftwareModuleType("test", "test", "test", 1));
type.setDescription("another");
final SoftwareModuleType updated = softwareManagement.updateSoftwareModuleType(type);
assertThat(type).as("Changed entity is not equal to the previous version").isNotEqualTo(updated);
}
@Test
@Description("Verify that no proxy of the entity manager has an influence on the equals or hashcode result.")
public void managedEntityIsEqualToUnamangedObjectWithSameKey() {
final SoftwareModuleType type = softwareManagement
.createSoftwareModuleType(new JpaSoftwareModuleType("test", "test", "test", 1));
final JpaSoftwareModuleType mock = new JpaSoftwareModuleType("test", "test", "test", 1);
mock.setId(type.getId());
mock.setOptLockRevision(type.getOptLockRevision());
mock.setTenant(type.getTenant());
assertThat(type).as("managed entity is equal to regular object with same content").isEqualTo(mock);
assertThat(type.hashCode()).as("managed entity has same hash code as regular object with same content")
.isEqualTo(mock.hashCode());
}
@Test
@Description("Verfies that updated entities do not have the same hashcode.")
public void updatedEntitiesHaveDifferentHashcodes() {
final SoftwareModuleType type = softwareManagement
.createSoftwareModuleType(new JpaSoftwareModuleType("test", "test", "test", 1));
assertThat(type.hashCode()).as("persited entity does not have same hashcode as regular object")
.isNotEqualTo(new JpaSoftwareModuleType("test", "test", "test", 1).hashCode());
final int beforeChange = type.hashCode();
type.setDescription("another");
assertThat(type.hashCode())
.as("Changed entity has no different hashcode than the previous version until updated in repository")
.isEqualTo(beforeChange);
final SoftwareModuleType updated = softwareManagement.updateSoftwareModuleType(type);
assertThat(type.hashCode()).as("Updated entity has different hashcode than the previous version")
.isNotEqualTo(updated.hashCode());
}
}

View File

@@ -0,0 +1,90 @@
/**
* 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.rsql;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.repository.ActionFields;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.Target;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("RSQL filter actions")
public class RSQLActionFieldsTest extends AbstractIntegrationTest {
private Target target;
private JpaAction action;
@Before
public void setupBeforeTest() {
target = new JpaTarget("targetId123");
target.setDescription("targetId123");
targetManagement.createTarget(target);
action = new JpaAction();
action.setActionType(ActionType.SOFT);
target.getActions().add(action);
action.setTarget(target);
actionRepository.save(action);
for (int i = 0; i < 10; i++) {
final JpaAction newAction = new JpaAction();
newAction.setActionType(ActionType.SOFT);
newAction.setActive(i % 2 == 0);
newAction.setTarget(target);
actionRepository.save(newAction);
target.getActions().add(newAction);
}
}
@Test
@Description("Test filter action by id")
public void testFilterByParameterId() {
assertRSQLQuery(ActionFields.ID.name() + "==" + action.getId(), 1);
assertRSQLQuery(ActionFields.ID.name() + "==noExist*", 0);
assertRSQLQuery(ActionFields.ID.name() + "=in=(" + action.getId() + ",1000000)", 1);
assertRSQLQuery(ActionFields.ID.name() + "=out=(" + action.getId() + ",1000000)", 10);
}
@Test
@Description("Test action by status")
public void testFilterByParameterStatus() {
assertRSQLQuery(ActionFields.STATUS.name() + "==pending", 5);
assertRSQLQuery(ActionFields.STATUS.name() + "=in=(pending)", 5);
assertRSQLQuery(ActionFields.STATUS.name() + "=out=(pending)", 6);
try {
assertRSQLQuery(ActionFields.STATUS.name() + "==true", 5);
fail("Missing expected RSQLParameterUnsupportedFieldException because status cannot be compared with 'true'");
} catch (final RSQLParameterUnsupportedFieldException e) {
}
}
private void assertRSQLQuery(final String rsqlParam, final long expectedEntities) {
final Slice<Action> findEnitity = deploymentManagement.findActionsByTarget(rsqlParam, target,
new PageRequest(0, 100));
final long countAllEntities = deploymentManagement.countActionsByTarget(rsqlParam, target);
assertThat(findEnitity).isNotNull();
assertThat(countAllEntities).isEqualTo(expectedEntities);
}
}

View File

@@ -0,0 +1,149 @@
/**
* 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.rsql;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import java.util.Arrays;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.TestDataUtil;
import org.eclipse.hawkbit.repository.DistributionSetFields;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("RSQL filter distribution set")
public class RSQLDistributionSetFieldTest extends AbstractIntegrationTest {
@Before
public void seuptBeforeTest() {
DistributionSet ds = TestDataUtil.generateDistributionSet("DS", softwareManagement, distributionSetManagement);
ds.setDescription("DS");
ds = distributionSetManagement.updateDistributionSet(ds);
distributionSetManagement
.createDistributionSetMetadata(new JpaDistributionSetMetadata("metaKey", ds, "metaValue"));
DistributionSet ds2 = TestDataUtil
.generateDistributionSets("NewDS", 3, softwareManagement, distributionSetManagement).get(0);
ds2.setDescription("DS%");
ds2 = distributionSetManagement.updateDistributionSet(ds2);
distributionSetManagement
.createDistributionSetMetadata(new JpaDistributionSetMetadata("metaKey", ds2, "value"));
final DistributionSetTag targetTag = tagManagement.createDistributionSetTag(new JpaDistributionSetTag("Tag1"));
tagManagement.createDistributionSetTag(new JpaDistributionSetTag("Tag2"));
tagManagement.createDistributionSetTag(new JpaDistributionSetTag("Tag3"));
tagManagement.createDistributionSetTag(new JpaDistributionSetTag("Tag4"));
distributionSetManagement.assignTag(Arrays.asList(ds.getId(), ds2.getId()), targetTag);
}
@Test
@Description("Test filter distribution set by id")
public void testFilterByParameterId() {
assertRSQLQuery(DistributionSetFields.ID.name() + "==*", 4);
}
@Test
@Description("Test filter distribution set by name")
public void testFilterByParameterName() {
assertRSQLQuery(DistributionSetFields.NAME.name() + "==DS", 1);
assertRSQLQuery(DistributionSetFields.NAME.name() + "==*DS", 4);
assertRSQLQuery(DistributionSetFields.NAME.name() + "==noExist*", 0);
assertRSQLQuery(DistributionSetFields.NAME.name() + "=in=(DS,notexist)", 1);
assertRSQLQuery(DistributionSetFields.NAME.name() + "=out=(DS,notexist)", 3);
}
@Test
@Description("Test filter distribution set by description")
public void testFilterByParameterDescription() {
assertRSQLQuery(DistributionSetFields.DESCRIPTION.name() + "==DS", 1);
assertRSQLQuery(DistributionSetFields.DESCRIPTION.name() + "==DS*", 2);
assertRSQLQuery(DistributionSetFields.DESCRIPTION.name() + "==DS%", 1);
assertRSQLQuery(DistributionSetFields.DESCRIPTION.name() + "==noExist*", 0);
assertRSQLQuery(DistributionSetFields.DESCRIPTION.name() + "=in=(DS,notexist)", 1);
assertRSQLQuery(DistributionSetFields.DESCRIPTION.name() + "=out=(DS,notexist)", 3);
}
@Test
@Description("Test filter distribution set by version")
public void testFilterByParameterVersion() {
assertRSQLQuery(DistributionSetFields.VERSION.name() + "==v1.0", 2);
assertRSQLQuery(DistributionSetFields.VERSION.name() + "!=v1.0", 2);
assertRSQLQuery(DistributionSetFields.VERSION.name() + "=in=(v1.0,v1.1)", 3);
assertRSQLQuery(DistributionSetFields.VERSION.name() + "=out=(v1.0,error)", 2);
}
@Test
@Description("Test filter distribution set by complete property")
public void testFilterByAttribute() {
assertRSQLQuery(DistributionSetFields.COMPLETE.name() + "==true", 4);
try {
assertRSQLQuery(DistributionSetFields.COMPLETE.name() + "==noExist*", 0);
fail("Expected RSQLParameterSyntaxException");
} catch (final RSQLParameterSyntaxException e) {
}
assertRSQLQuery(DistributionSetFields.COMPLETE.name() + "=in=(true)", 4);
assertRSQLQuery(DistributionSetFields.COMPLETE.name() + "=out=(true)", 0);
}
@Test
@Description("Test filter distribution set by tag")
public void testFilterByTag() {
assertRSQLQuery(DistributionSetFields.TAG.name() + "==Tag1", 2);
assertRSQLQuery(DistributionSetFields.TAG.name() + "==T*", 2);
assertRSQLQuery(DistributionSetFields.TAG.name() + "==noExist*", 0);
assertRSQLQuery(DistributionSetFields.TAG.name() + "=in=(Tag1,notexist)", 2);
assertRSQLQuery(DistributionSetFields.TAG.name() + "=out=(Tag1,notexist)", 0);
}
@Test
@Description("Test filter distribution set by type")
public void testFilterByType() {
assertRSQLQuery(DistributionSetFields.TYPE.name() + "==ecl_os_app_jvm", 4);
assertRSQLQuery(DistributionSetFields.TYPE.name() + "==noExist*", 0);
assertRSQLQuery(DistributionSetFields.TYPE.name() + "=in=(ecl_os_app_jvm,ecl)", 4);
assertRSQLQuery(DistributionSetFields.TYPE.name() + "=out=(ecl_os_app_jvm)", 0);
}
@Test
@Description("")
public void testFilterByMetadata() {
assertRSQLQuery(DistributionSetFields.METADATA.name() + ".metaKey==metaValue", 1);
assertRSQLQuery(DistributionSetFields.METADATA.name() + ".metaKey==*v*", 2);
assertRSQLQuery(DistributionSetFields.METADATA.name() + ".metaKey==noExist*", 0);
assertRSQLQuery(DistributionSetFields.METADATA.name() + ".metaKey=in=(metaValue,notexist)", 1);
assertRSQLQuery(DistributionSetFields.METADATA.name() + ".metaKey=out=(metaValue,notexist)", 1);
assertRSQLQuery(DistributionSetFields.METADATA.name() + ".notExist==metaValue", 0);
}
private void assertRSQLQuery(final String rsqlParam, final long excpectedEntity) {
final Page<DistributionSet> find = distributionSetManagement.findDistributionSetsAll(rsqlParam,
new PageRequest(0, 100), false);
final long countAll = find.getTotalElements();
assertThat(find).as("Founded entity is should not be null").isNotNull();
assertThat(countAll).as("Founded entity size is wrong").isEqualTo(excpectedEntity);
}
}

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.rsql;
import static org.fest.assertions.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.TestDataUtil;
import org.eclipse.hawkbit.repository.DistributionSetMetadataFields;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("RSQL filter distribution set metadata")
public class RSQLDistributionSetMetadataFieldsTest extends AbstractIntegrationTest {
private Long distributionSetId;
@Before
public void setupBeforeTest() {
final DistributionSet distributionSet = TestDataUtil.generateDistributionSet("DS", softwareManagement,
distributionSetManagement);
distributionSetId = distributionSet.getId();
final List<DistributionSetMetadata> metadata = new ArrayList<>();
for (int i = 0; i < 5; i++) {
metadata.add(new JpaDistributionSetMetadata("" + i, distributionSet, "" + i));
}
distributionSetManagement.createDistributionSetMetadata(metadata);
}
@Test
@Description("Test filter distribution set metadata by key")
public void testFilterByParameterKey() {
assertRSQLQuery(DistributionSetMetadataFields.KEY.name() + "==1", 1);
assertRSQLQuery(DistributionSetMetadataFields.KEY.name() + "!=1", 4);
assertRSQLQuery(DistributionSetMetadataFields.KEY.name() + "=in=(1,2)", 2);
assertRSQLQuery(DistributionSetMetadataFields.KEY.name() + "=out=(1,2)", 3);
}
@Test
@Description("Test filter distribution set metadata by value")
public void testFilterByParameterValue() {
assertRSQLQuery(DistributionSetMetadataFields.VALUE.name() + "==1", 1);
assertRSQLQuery(DistributionSetMetadataFields.VALUE.name() + "!=1", 4);
assertRSQLQuery(DistributionSetMetadataFields.VALUE.name() + "=in=(1,2)", 2);
assertRSQLQuery(DistributionSetMetadataFields.VALUE.name() + "=out=(1,2)", 3);
}
private void assertRSQLQuery(final String rsqlParam, final long expectedEntities) {
final Page<DistributionSetMetadata> findEnitity = distributionSetManagement
.findDistributionSetMetadataByDistributionSetId(distributionSetId, rsqlParam, new PageRequest(0, 100));
final long countAllEntities = findEnitity.getTotalElements();
assertThat(findEnitity).isNotNull();
assertThat(countAllEntities).isEqualTo(expectedEntities);
}
}

View File

@@ -0,0 +1,95 @@
/**
* 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.rsql;
import static org.fest.assertions.api.Assertions.assertThat;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.TestDataUtil;
import org.eclipse.hawkbit.repository.RolloutGroupFields;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition;
import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("RSQL filter rollout group")
public class RSQLRolloutGroupFields extends AbstractIntegrationTest {
private Long rolloutGroupId;
private Rollout rollout;
@Before
public void seuptBeforeTest() {
final int amountTargets = 20;
targetManagement.createTargets(TestDataUtil.buildTargetFixtures(amountTargets, "rollout", "rollout"));
final DistributionSet dsA = TestDataUtil.generateDistributionSet("", softwareManagement,
distributionSetManagement);
rollout = createRollout("rollout1", 4, dsA.getId(), "controllerId==rollout*");
rollout = rolloutManagement.findRolloutById(rollout.getId());
this.rolloutGroupId = rollout.getRolloutGroups().get(0).getId();
}
@Test
@Description("Test filter rollout group by id")
public void testFilterByParameterId() {
assertRSQLQuery(RolloutGroupFields.ID.name() + "==" + rolloutGroupId, 1);
assertRSQLQuery(RolloutGroupFields.ID.name() + "==noExist*", 0);
assertRSQLQuery(RolloutGroupFields.ID.name() + "=in=(" + rolloutGroupId + ")", 1);
assertRSQLQuery(RolloutGroupFields.ID.name() + "=out=(" + rolloutGroupId + ")", 3);
}
@Test
@Description("Test filter rollout group by name")
public void testFilterByParameterName() {
assertRSQLQuery(RolloutGroupFields.NAME.name() + "==group-1", 1);
assertRSQLQuery(RolloutGroupFields.NAME.name() + "==*", 4);
assertRSQLQuery(RolloutGroupFields.NAME.name() + "==noExist*", 0);
assertRSQLQuery(RolloutGroupFields.NAME.name() + "=in=(group-1,group-2)", 2);
assertRSQLQuery(RolloutGroupFields.NAME.name() + "=out=(group-1,group-2)", 2);
}
@Test
@Description("Test filter rollout group by description")
public void testFilterByParameterDescription() {
assertRSQLQuery(RolloutGroupFields.DESCRIPTION.name() + "==group-1", 1);
assertRSQLQuery(RolloutGroupFields.DESCRIPTION.name() + "==group*", 4);
assertRSQLQuery(RolloutGroupFields.DESCRIPTION.name() + "==noExist*", 0);
assertRSQLQuery(RolloutGroupFields.DESCRIPTION.name() + "=in=(group-1,notexist)", 1);
assertRSQLQuery(RolloutGroupFields.DESCRIPTION.name() + "=out=(group-1,notexist)", 3);
}
private void assertRSQLQuery(final String rsqlParam, final long expcetedTargets) {
final Page<RolloutGroup> findTargetPage = rolloutGroupManagement.findRolloutGroupsAll(rollout, rsqlParam,
new PageRequest(0, 100));
final long countTargetsAll = findTargetPage.getTotalElements();
assertThat(findTargetPage).isNotNull();
assertThat(countTargetsAll).isEqualTo(expcetedTargets);
}
private Rollout createRollout(final String name, final int amountGroups, final long distributionSetId,
final String targetFilterQuery) {
final Rollout rollout = new JpaRollout();
rollout.setDistributionSet(distributionSetManagement.findDistributionSetById(distributionSetId));
rollout.setName(name);
rollout.setTargetFilterQuery(targetFilterQuery);
return rolloutManagement.createRollout(rollout, amountGroups, new RolloutGroupConditionBuilder()
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build());
}
}

View File

@@ -0,0 +1,112 @@
/**
* 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.rsql;
import static org.fest.assertions.api.Assertions.assertThat;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.repository.SoftwareModuleFields;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("RSQL filter software module")
public class RSQLSoftwareModuleFieldTest extends AbstractIntegrationTest {
@Before
public void setupBeforeTest() {
final JpaSoftwareModule ah = (JpaSoftwareModule) softwareManagement
.createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", "agent-hub", ""));
softwareManagement.createSoftwareModule(new JpaSoftwareModule(runtimeType, "oracle-jre", "1.7.2", "aa", ""));
softwareManagement.createSoftwareModule(new JpaSoftwareModule(osType, "poky", "3.0.2", "aa", ""));
final JpaSoftwareModule ah2 = (JpaSoftwareModule) softwareManagement
.createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub2", "1.0.1", "agent-hub2", ""));
final SoftwareModuleMetadata softwareModuleMetadata = new JpaSoftwareModuleMetadata("metaKey", ah, "metaValue");
softwareManagement.createSoftwareModuleMetadata(softwareModuleMetadata);
final SoftwareModuleMetadata softwareModuleMetadata2 = new JpaSoftwareModuleMetadata("metaKey", ah2, "value");
softwareManagement.createSoftwareModuleMetadata(softwareModuleMetadata2);
}
@Test
@Description("Test filter software module by id")
public void testFilterByParameterId() {
assertRSQLQuery(SoftwareModuleFields.ID.name() + "==*", 4);
}
@Test
@Description("Test filter software module by name")
public void testFilterByParameterName() {
assertRSQLQuery(SoftwareModuleFields.NAME.name() + "==agent-hub", 1);
assertRSQLQuery(SoftwareModuleFields.NAME.name() + "==agent-hub*", 2);
assertRSQLQuery(SoftwareModuleFields.NAME.name() + "!=agent-hub*", 2);
assertRSQLQuery(SoftwareModuleFields.NAME.name() + "==noExist*", 0);
assertRSQLQuery(SoftwareModuleFields.NAME.name() + "=in=(agent-hub,notexist)", 1);
assertRSQLQuery(SoftwareModuleFields.NAME.name() + "=out=(agent-hub,notexist)", 3);
}
@Test
@Description("Test filter software module by description")
public void testFilterByParameterDescription() {
assertRSQLQuery(SoftwareModuleFields.DESCRIPTION.name() + "==agent-hub", 1);
assertRSQLQuery(SoftwareModuleFields.DESCRIPTION.name() + "==noExist*", 0);
assertRSQLQuery(SoftwareModuleFields.DESCRIPTION.name() + "=in=(agent-hub,notexist)", 1);
assertRSQLQuery(SoftwareModuleFields.DESCRIPTION.name() + "=out=(agent-hub,notexist)", 3);
}
@Test
@Description("Test filter software module by version")
public void testFilterByParameterVersion() {
assertRSQLQuery(SoftwareModuleFields.VERSION.name() + "==1.0.1", 2);
assertRSQLQuery(SoftwareModuleFields.VERSION.name() + "!=v1.0", 4);
assertRSQLQuery(SoftwareModuleFields.VERSION.name() + "=in=(1.0.1,1.0.2)", 2);
assertRSQLQuery(SoftwareModuleFields.VERSION.name() + "=out=(1.0.1)", 2);
}
@Test
@Description("Test filter software module by type")
public void testFilterByType() {
assertRSQLQuery(SoftwareModuleFields.TYPE.name() + "==application", 2);
assertRSQLQuery(SoftwareModuleFields.TYPE.name() + "==noExist*", 0);
assertRSQLQuery(SoftwareModuleFields.TYPE.name() + "=in=(application)", 2);
assertRSQLQuery(SoftwareModuleFields.TYPE.name() + "=out=(application)", 2);
}
@Test
@Description("Test filter software module by metadata")
public void testFilterByMetadata() {
assertRSQLQuery(SoftwareModuleFields.METADATA.name() + ".metaKey==metaValue", 1);
assertRSQLQuery(SoftwareModuleFields.METADATA.name() + ".metaKey==*v*", 2);
assertRSQLQuery(SoftwareModuleFields.METADATA.name() + ".metaKey==noExist*", 0);
assertRSQLQuery(SoftwareModuleFields.METADATA.name() + ".metaKey=in=(metaValue,value)", 2);
assertRSQLQuery(SoftwareModuleFields.METADATA.name() + ".metaKey=out=(metaValue,notexist)", 1);
assertRSQLQuery(SoftwareModuleFields.METADATA.name() + ".notExist==metaValue", 0);
}
private void assertRSQLQuery(final String rsqlParam, final long excpectedEntity) {
final Page<SoftwareModule> find = softwareManagement.findSoftwareModulesByPredicate(rsqlParam,
new PageRequest(0, 100));
final long countAll = find.getTotalElements();
assertThat(find).isNotNull();
assertThat(countAll).isEqualTo(excpectedEntity);
}
}

View File

@@ -0,0 +1,80 @@
/**
* 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.rsql;
import static org.fest.assertions.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.TestDataUtil;
import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("RSQL filter software module metadata")
public class RSQLSoftwareModuleMetadataFieldsTest extends AbstractIntegrationTest {
private Long softwareModuleId;
@Before
public void setupBeforeTest() {
final SoftwareModule softwareModule = softwareManagement.createSoftwareModule(
new JpaSoftwareModule(TestDataUtil.findOrCreateSoftwareModuleType(softwareManagement, "application"),
"application", "1.0.0", "Desc", "vendor Limited, California"));
softwareModuleId = softwareModule.getId();
final List<SoftwareModuleMetadata> metadata = new ArrayList<>();
for (int i = 0; i < 5; i++) {
metadata.add(new JpaSoftwareModuleMetadata("" + i, softwareModule, "" + i));
}
softwareManagement.createSoftwareModuleMetadata(metadata);
}
@Test
@Description("Test filter software module metadata by key")
public void testFilterByParameterKey() {
assertRSQLQuery(SoftwareModuleMetadataFields.KEY.name() + "==1", 1);
assertRSQLQuery(SoftwareModuleMetadataFields.KEY.name() + "!=1", 4);
assertRSQLQuery(SoftwareModuleMetadataFields.KEY.name() + "=in=(1,2)", 2);
assertRSQLQuery(SoftwareModuleMetadataFields.KEY.name() + "=out=(1,2)", 3);
}
@Test
@Description("Test fitler software module metadata status by value")
public void testFilterByParameterValue() {
assertRSQLQuery(SoftwareModuleMetadataFields.VALUE.name() + "==1", 1);
assertRSQLQuery(SoftwareModuleMetadataFields.VALUE.name() + "!=1", 4);
assertRSQLQuery(SoftwareModuleMetadataFields.VALUE.name() + "=in=(1,2)", 2);
assertRSQLQuery(SoftwareModuleMetadataFields.VALUE.name() + "=out=(1,2)", 3);
}
private void assertRSQLQuery(final String rsqlParam, final long expectedEntities) {
final Page<SoftwareModuleMetadata> findEnitity = softwareManagement
.findSoftwareModuleMetadataBySoftwareModuleId(softwareModuleId, rsqlParam, new PageRequest(0, 100));
final long countAllEntities = findEnitity.getTotalElements();
assertThat(findEnitity).isNotNull();
assertThat(countAllEntities).isEqualTo(expectedEntities);
}
}

View File

@@ -0,0 +1,68 @@
/**
* 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.rsql;
import static org.fest.assertions.api.Assertions.assertThat;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.junit.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("RSQL filter software module test type")
public class RSQLSoftwareModuleTypeFieldsTest extends AbstractIntegrationTest {
@Test
@Description("Test filter software module test type by id")
public void testFilterByParameterId() {
assertRSQLQuery(SoftwareModuleTypeFields.ID.name() + "==*", 3);
}
@Test
@Description("Test filter software module test type by name")
public void testFilterByParameterName() {
assertRSQLQuery(SoftwareModuleTypeFields.NAME.name() + "==ECL*", 3);
}
@Test
@Description("Test filter software module test type by description")
public void testFilterByParameterDescription() {
assertRSQLQuery(SoftwareModuleTypeFields.DESCRIPTION.name() + "==Updated*", 3);
assertRSQLQuery(SoftwareModuleTypeFields.DESCRIPTION.name() + "==noExist*", 0);
}
@Test
@Description("Test filter software module test type by key")
public void testFilterByParameterKey() {
assertRSQLQuery(SoftwareModuleTypeFields.KEY.name() + "==os", 1);
assertRSQLQuery(SoftwareModuleTypeFields.KEY.name() + "=in=(os)", 1);
assertRSQLQuery(SoftwareModuleTypeFields.KEY.name() + "=out=(os)", 2);
}
@Test
@Description("Test filter software module test type by max")
public void testFilterByMaxAssignment() {
assertRSQLQuery(SoftwareModuleTypeFields.MAXASSIGNMENTS.name() + "==1", 3);
}
private void assertRSQLQuery(final String rsqlParam, final long excpectedEntity) {
final Page<SoftwareModuleType> find = softwareManagement.findSoftwareModuleTypesAll(rsqlParam,
new PageRequest(0, 100));
final long countAll = find.getTotalElements();
assertThat(find).isNotNull();
assertThat(countAll).isEqualTo(excpectedEntity);
}
}

View File

@@ -0,0 +1,120 @@
/**
* 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.rsql;
import static org.fest.assertions.api.Assertions.assertThat;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.repository.TagFields;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("RSQL filter target and distribution set tags")
public class RSQLTagFieldsTest extends AbstractIntegrationTest {
@Before
public void seuptBeforeTest() {
for (int i = 0; i < 5; i++) {
final TargetTag targetTag = new JpaTargetTag("" + i, "" + i, i % 2 == 0 ? "red" : "blue");
tagManagement.createTargetTag(targetTag);
final DistributionSetTag distributionSetTag = new JpaDistributionSetTag("" + i, "" + i,
i % 2 == 0 ? "red" : "blue");
tagManagement.createDistributionSetTag(distributionSetTag);
}
}
@Test
@Description("Test filter target tag by name")
public void testFilterTargetTagByParameterName() {
assertRSQLQueryTarget(TagFields.NAME.name() + "==1", 1);
assertRSQLQueryTarget(TagFields.NAME.name() + "==*", 5);
assertRSQLQueryTarget(TagFields.NAME.name() + "==noExist*", 0);
assertRSQLQueryTarget(TagFields.NAME.name() + "=in=(1,notexist)", 1);
assertRSQLQueryTarget(TagFields.NAME.name() + "=out=(1,notexist)", 4);
}
@Test
@Description("Test filter target tag by description")
public void testFilterTargetTagByParameterDescription() {
assertRSQLQueryTarget(TagFields.DESCRIPTION.name() + "==1", 1);
assertRSQLQueryTarget(TagFields.DESCRIPTION.name() + "==*", 5);
assertRSQLQueryTarget(TagFields.DESCRIPTION.name() + "==noExist*", 0);
assertRSQLQueryTarget(TagFields.DESCRIPTION.name() + "=in=(1,notexist)", 1);
assertRSQLQueryTarget(TagFields.DESCRIPTION.name() + "=out=(1,notexist)", 4);
}
@Test
@Description("Test filter target tag by colour")
public void testFilterTargetTagByParameterColour() {
assertRSQLQueryTarget(TagFields.COLOUR.name() + "==red", 3);
assertRSQLQueryTarget(TagFields.COLOUR.name() + "==r*", 3);
assertRSQLQueryTarget(TagFields.COLOUR.name() + "==noExist*", 0);
assertRSQLQueryTarget(TagFields.COLOUR.name() + "=in=(red,notexist)", 3);
assertRSQLQueryTarget(TagFields.COLOUR.name() + "=out=(red,notexist)", 2);
}
@Test
@Description("Test filter distribution set tag by name")
public void testFilterDistributionSetTagByParameterName() {
assertRSQLQueryDistributionSet(TagFields.NAME.name() + "==1", 1);
assertRSQLQueryDistributionSet(TagFields.NAME.name() + "==*", 5);
assertRSQLQueryDistributionSet(TagFields.NAME.name() + "==noExist*", 0);
assertRSQLQueryDistributionSet(TagFields.NAME.name() + "=in=(1,2)", 2);
assertRSQLQueryDistributionSet(TagFields.NAME.name() + "=out=(1,2)", 3);
}
@Test
@Description("Test filter distribution set by description")
public void testFilterDistributionSetTagByParameterDescription() {
assertRSQLQueryDistributionSet(TagFields.DESCRIPTION.name() + "==1", 1);
assertRSQLQueryDistributionSet(TagFields.DESCRIPTION.name() + "==*", 5);
assertRSQLQueryDistributionSet(TagFields.DESCRIPTION.name() + "==noExist*", 0);
assertRSQLQueryDistributionSet(TagFields.DESCRIPTION.name() + "=in=(1,2)", 2);
assertRSQLQueryDistributionSet(TagFields.DESCRIPTION.name() + "=out=(1,2)", 3);
}
@Test
@Description("Test filter distribution set by colour")
public void testFilterDistributionSetTagByParameterColour() {
assertRSQLQueryDistributionSet(TagFields.COLOUR.name() + "==red", 3);
assertRSQLQueryDistributionSet(TagFields.COLOUR.name() + "==r*", 3);
assertRSQLQueryDistributionSet(TagFields.COLOUR.name() + "==noExist*", 0);
assertRSQLQueryDistributionSet(TagFields.COLOUR.name() + "=in=(red,notexist)", 3);
assertRSQLQueryDistributionSet(TagFields.COLOUR.name() + "=out=(red,notexist)", 2);
}
private void assertRSQLQueryDistributionSet(final String rsqlParam, final long expectedEntities) {
final Page<DistributionSetTag> findEnitity = tagManagement.findAllDistributionSetTags(rsqlParam,
new PageRequest(0, 100));
final long countAllEntities = findEnitity.getTotalElements();
assertThat(findEnitity).isNotNull();
assertThat(countAllEntities).isEqualTo(expectedEntities);
}
private void assertRSQLQueryTarget(final String rsqlParam, final long expectedEntities) {
final Page<TargetTag> findEnitity = tagManagement.findAllTargetTags(rsqlParam, new PageRequest(0, 100));
final long countAllEntities = findEnitity.getTotalElements();
assertThat(findEnitity).isNotNull();
assertThat(countAllEntities).isEqualTo(expectedEntities);
}
}

View File

@@ -0,0 +1,175 @@
/**
* 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.rsql;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import java.util.Arrays;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.TestDataUtil;
import org.eclipse.hawkbit.repository.TargetFields;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetInfo;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@Features("Component Tests - Repository")
@Stories("RSQL filter target")
public class RSQLTargetFieldTest extends AbstractIntegrationTest {
@Before
public void seuptBeforeTest() {
final DistributionSet ds = TestDataUtil.generateDistributionSet("AssignedDs", softwareManagement,
distributionSetManagement);
final JpaTarget target = new JpaTarget("targetId123");
target.setDescription("targetId123");
final TargetInfo targetInfo = new JpaTargetInfo(target);
targetInfo.getControllerAttributes().put("revision", "1.1");
target.setTargetInfo(targetInfo);
((JpaTargetInfo) target.getTargetInfo()).setUpdateStatus(TargetUpdateStatus.PENDING);
targetManagement.createTarget(target);
final JpaTarget target2 = new JpaTarget("targetId1234");
target2.setDescription("targetId1234");
final TargetInfo targetInfo2 = new JpaTargetInfo(target2);
targetInfo2.getControllerAttributes().put("revision", "1.2");
target2.setTargetInfo(targetInfo2);
targetManagement.createTarget(target2);
targetManagement.createTarget(new JpaTarget("targetId1235"));
targetManagement.createTarget(new JpaTarget("targetId1236"));
final TargetTag targetTag = tagManagement.createTargetTag(new JpaTargetTag("Tag1"));
tagManagement.createTargetTag(new JpaTargetTag("Tag2"));
tagManagement.createTargetTag(new JpaTargetTag("Tag3"));
tagManagement.createTargetTag(new JpaTargetTag("Tag4"));
targetManagement.assignTag(Arrays.asList(target.getControllerId(), target2.getControllerId()), targetTag);
deploymentManagement.assignDistributionSet(ds.getId(), target.getControllerId());
}
@Test
@Description("Test filter target by (controller) id")
public void testFilterByParameterId() {
assertRSQLQuery(TargetFields.ID.name() + "==targetId123", 1);
assertRSQLQuery(TargetFields.ID.name() + "==target*", 4);
assertRSQLQuery(TargetFields.ID.name() + "==noExist*", 0);
assertRSQLQuery(TargetFields.ID.name() + "=in=(targetId123,notexist)", 1);
assertRSQLQuery(TargetFields.ID.name() + "=out=(targetId123,notexist)", 3);
}
@Test
@Description("Test filter target by name")
public void testFilterByParameterName() {
assertRSQLQuery(TargetFields.NAME.name() + "==targetId123", 1);
assertRSQLQuery(TargetFields.NAME.name() + "==target*", 4);
assertRSQLQuery(TargetFields.NAME.name() + "==noExist*", 0);
assertRSQLQuery(TargetFields.NAME.name() + "=in=(targetId123,notexist)", 1);
assertRSQLQuery(TargetFields.NAME.name() + "=out=(targetId123,notexist)", 3);
}
@Test
@Description("Test filter target by description")
public void testFilterByParameterDescription() {
assertRSQLQuery(TargetFields.DESCRIPTION.name() + "==targetId123", 1);
assertRSQLQuery(TargetFields.DESCRIPTION.name() + "==target*", 2);
assertRSQLQuery(TargetFields.DESCRIPTION.name() + "==noExist*", 0);
assertRSQLQuery(TargetFields.DESCRIPTION.name() + "=in=(targetId123,notexist)", 1);
assertRSQLQuery(TargetFields.DESCRIPTION.name() + "=out=(targetId123,notexist)", 1);
}
@Test
@Description("Test filter target by controller id")
public void testFilterByParameterControllerId() {
assertRSQLQuery(TargetFields.CONTROLLERID.name() + "==targetId123", 1);
assertRSQLQuery(TargetFields.CONTROLLERID.name() + "==target*", 4);
assertRSQLQuery(TargetFields.CONTROLLERID.name() + "==noExist*", 0);
assertRSQLQuery(TargetFields.CONTROLLERID.name() + "=in=(targetId123,notexist)", 1);
assertRSQLQuery(TargetFields.CONTROLLERID.name() + "=out=(targetId123,notexist)", 3);
}
@Test
@Description("Test filter target by status")
public void testFilterByParameterUpdateStatus() {
assertRSQLQuery(TargetFields.UPDATESTATUS.name() + "==pending", 1);
assertRSQLQuery(TargetFields.UPDATESTATUS.name() + "!=pending", 3);
try {
assertRSQLQuery(TargetFields.UPDATESTATUS.name() + "==noExist*", 0);
fail("RSQLParameterUnsupportedFieldException was expected since update status unknown");
} catch (final RSQLParameterUnsupportedFieldException e) {
// test ok - exception was excepted
}
assertRSQLQuery(TargetFields.UPDATESTATUS.name() + "=in=(pending,error)", 1);
assertRSQLQuery(TargetFields.UPDATESTATUS.name() + "=out=(pending,error)", 3);
}
@Test
@Description("Test filter target by attribute")
public void testFilterByAttribute() {
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision==1.1", 1);
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision==1*", 2);
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision==noExist*", 0);
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision=in=(1.1,notexist)", 1);
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision=out=(1.1)", 1);
}
@Test
@Description("Test filter target by assigned ds name")
public void testFilterByAssignedDsName() {
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".name==AssignedDs", 1);
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".name==A*", 1);
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".name==noExist*", 0);
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".name=in=(AssignedDs,notexist)", 1);
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".name=out=(AssignedDs,notexist)", 0);
}
@Test
@Description("Test filter target by assigned ds version")
public void testFilterByAssignedDsVersion() {
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".version==v1.0", 1);
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".version==*1*", 1);
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".version==noExist*", 0);
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".version=in=(v1.0,notexist)", 1);
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".version=out=(v1.0,notexist)", 0);
}
@Test
@Description("Test filter target by tag")
public void testFilterByTag() {
assertRSQLQuery(TargetFields.TAG.name() + "==Tag1", 2);
assertRSQLQuery(TargetFields.TAG.name() + "==T*", 2);
assertRSQLQuery(TargetFields.TAG.name() + "==noExist*", 0);
assertRSQLQuery(TargetFields.TAG.name() + "=in=(Tag1,notexist)", 2);
assertRSQLQuery(TargetFields.TAG.name() + "=out=(Tag1,notexist)", 0);
}
private void assertRSQLQuery(final String rsqlParam, final long expcetedTargets) {
final Page<Target> findTargetPage = targetManagement.findTargetsAll(rsqlParam, new PageRequest(0, 100));
final long countTargetsAll = findTargetPage.getTotalElements();
assertThat(findTargetPage).isNotNull();
assertThat(countTargetsAll).isEqualTo(expcetedTargets);
}
}

View File

@@ -0,0 +1,280 @@
/**
* 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.rsql;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.Attribute;
import org.eclipse.hawkbit.repository.DistributionSetFields;
import org.eclipse.hawkbit.repository.FieldNameProvider;
import org.eclipse.hawkbit.repository.SoftwareModuleFields;
import org.eclipse.hawkbit.repository.TargetFields;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
@RunWith(MockitoJUnitRunner.class)
@Features("Component Tests - Repository")
@Stories("RSQL search utility")
// TODO: fully document tests -> @Description for long text and reasonable
// method name as short text
public class RSQLUtilityTest {
@Mock
private Root<Object> baseSoftwareModuleRootMock;
@Mock
private CriteriaQuery<SoftwareModule> criteriaQueryMock;
@Mock
private CriteriaBuilder criteriaBuilderMock;
@Mock
private Attribute attribute;
@Test
public void wrongRsqlSyntaxThrowSyntaxException() {
final String wrongRSQL = "name==abc;d";
try {
RSQLUtility.parse(wrongRSQL, SoftwareModuleFields.class).toPredicate(baseSoftwareModuleRootMock,
criteriaQueryMock, criteriaBuilderMock);
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
} catch (final RSQLParameterSyntaxException e) {
}
}
@Test
public void wrongFieldThrowUnsupportedFieldException() {
final String wrongRSQL = "unknownField==abc";
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
try {
RSQLUtility.parse(wrongRSQL, SoftwareModuleFields.class).toPredicate(baseSoftwareModuleRootMock,
criteriaQueryMock, criteriaBuilderMock);
fail("Missing an expected RSQLParameterUnsupportedFieldException because of unknown RSQL field");
} catch (final RSQLParameterUnsupportedFieldException e) {
}
}
@Test
public void wrongRsqlMapSyntaxThrowSyntaxException() {
String wrongRSQL = TargetFields.ATTRIBUTE + "==abc";
try {
RSQLUtility.parse(wrongRSQL, TargetFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock,
criteriaBuilderMock);
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
} catch (final RSQLParameterUnsupportedFieldException e) {
}
wrongRSQL = TargetFields.ATTRIBUTE + ".unkwon.wrong==abc";
try {
RSQLUtility.parse(wrongRSQL, TargetFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock,
criteriaBuilderMock);
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
} catch (final RSQLParameterUnsupportedFieldException e) {
}
wrongRSQL = DistributionSetFields.METADATA + "==abc";
try {
RSQLUtility.parse(wrongRSQL, DistributionSetFields.class).toPredicate(baseSoftwareModuleRootMock,
criteriaQueryMock, criteriaBuilderMock);
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
} catch (final RSQLParameterUnsupportedFieldException e) {
}
}
@Test
public void wrongRsqlSubEntitySyntaxThrowSyntaxException() {
String wrongRSQL = TargetFields.ASSIGNEDDS + "==abc";
try {
RSQLUtility.parse(wrongRSQL, TargetFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock,
criteriaBuilderMock);
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
} catch (final RSQLParameterUnsupportedFieldException e) {
}
wrongRSQL = TargetFields.ASSIGNEDDS + ".unknownField==abc";
try {
RSQLUtility.parse(wrongRSQL, TargetFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock,
criteriaBuilderMock);
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
} catch (final RSQLParameterUnsupportedFieldException e) {
}
wrongRSQL = TargetFields.ASSIGNEDDS + ".unknownField.ToMuch==abc";
try {
RSQLUtility.parse(wrongRSQL, TargetFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock,
criteriaBuilderMock);
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
} catch (final RSQLParameterUnsupportedFieldException e) {
}
}
@Test
public <T> void correctRsqlBuildsPredicate() {
reset(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
final String correctRsql = "name==abc;version==1.2";
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
when(baseSoftwareModuleRootMock.get("version")).thenReturn(baseSoftwareModuleRootMock);
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.<String> greaterThanOrEqualTo(any(Expression.class), any(String.class)))
.thenReturn(mock(Predicate.class));
// test
RSQLUtility.parse(correctRsql, SoftwareModuleFields.class).toPredicate(baseSoftwareModuleRootMock,
criteriaQueryMock, criteriaBuilderMock);
// verfication
verify(criteriaBuilderMock, times(1)).and(any(Predicate.class));
}
@Test
public void correctRsqlBuildsNotLikePredicate() {
reset(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
final String correctRsql = "name!=abc";
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.<String> greaterThanOrEqualTo(any(Expression.class), any(String.class)))
.thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.upper(eq(pathOfString(baseSoftwareModuleRootMock))))
.thenReturn(pathOfString(baseSoftwareModuleRootMock));
// test
RSQLUtility.parse(correctRsql, SoftwareModuleFields.class).toPredicate(baseSoftwareModuleRootMock,
criteriaQueryMock, criteriaBuilderMock);
// verfication
verify(criteriaBuilderMock, times(1)).and(any(Predicate.class));
verify(criteriaBuilderMock, times(1)).notLike(eq(pathOfString(baseSoftwareModuleRootMock)),
eq("abc".toUpperCase()));
}
@Test
public void correctRsqlBuildsLikePredicateWithPercentage() {
reset(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
final String correctRsql = "name==a%";
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.<String> greaterThanOrEqualTo(any(Expression.class), any(String.class)))
.thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.upper(eq(pathOfString(baseSoftwareModuleRootMock))))
.thenReturn(pathOfString(baseSoftwareModuleRootMock));
// test
RSQLUtility.parse(correctRsql, SoftwareModuleFields.class).toPredicate(baseSoftwareModuleRootMock,
criteriaQueryMock, criteriaBuilderMock);
// verfication
verify(criteriaBuilderMock, times(1)).and(any(Predicate.class));
verify(criteriaBuilderMock, times(1)).like(eq(pathOfString(baseSoftwareModuleRootMock)),
eq("a\\%".toUpperCase()));
}
@Test
public void correctRsqlBuildsLessThanPredicate() {
reset(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
final String correctRsql = "name=lt=abc";
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.<String> greaterThanOrEqualTo(any(Expression.class), any(String.class)))
.thenReturn(mock(Predicate.class));
// test
RSQLUtility.parse(correctRsql, SoftwareModuleFields.class).toPredicate(baseSoftwareModuleRootMock,
criteriaQueryMock, criteriaBuilderMock);
// verfication
verify(criteriaBuilderMock, times(1)).and(any(Predicate.class));
verify(criteriaBuilderMock, times(1)).lessThan(eq(pathOfString(baseSoftwareModuleRootMock)), eq("abc"));
}
@Test
public void correctRsqlWithEnumValue() {
reset(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
final String correctRsql = "testfield==bumlux";
when(baseSoftwareModuleRootMock.get("testfield")).thenReturn(baseSoftwareModuleRootMock);
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) TestValueEnum.class);
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
// test
RSQLUtility.parse(correctRsql, TestFieldEnum.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock,
criteriaBuilderMock);
// verfication
verify(criteriaBuilderMock, times(1)).and(any(Predicate.class));
verify(criteriaBuilderMock, times(1)).equal(eq(baseSoftwareModuleRootMock), eq(TestValueEnum.BUMLUX));
}
@Test
public void wrongRsqlWithWrongEnumValue() {
reset(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
final String correctRsql = "testfield==unknownValue";
when(baseSoftwareModuleRootMock.get("testfield")).thenReturn(baseSoftwareModuleRootMock);
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) TestValueEnum.class);
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
try {
// test
RSQLUtility.parse(correctRsql, TestFieldEnum.class).toPredicate(baseSoftwareModuleRootMock,
criteriaQueryMock, criteriaBuilderMock);
fail("missing RSQLParameterUnsupportedFieldException for wrong enum value");
} catch (final RSQLParameterUnsupportedFieldException e) {
// nope expected
}
}
@SuppressWarnings("unchecked")
private <Y> Path<Y> pathOfString(final Path<?> path) {
return (Path<Y>) path;
}
private enum TestFieldEnum implements FieldNameProvider {
TESTFIELD;
/*
* (non-Javadoc)
*
* @see
* org.eclipse.hawkbit.server.rest.resource.model.FieldNameProvider#
* getFieldName()
*/
@Override
public String getFieldName() {
return "testfield";
}
}
private enum TestValueEnum {
BUMLUX;
}
}

View File

@@ -0,0 +1,94 @@
/**
* 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.utils;
import java.util.concurrent.Callable;
/**
* Helper to call a request multiple times regarding a given condition until
* timeout is reached.
*
*/
public final class MultipleInvokeHelper {
/**
* Call with timeout until result is not null.
*
* @param callable
* class
* @param timeout
* value
* @param pollInterval
* value
* @return
* @throws Exception
*/
public static <T> T doWithTimeoutUntilResultIsNotNull(final Callable<T> callable, final long timeout,
final long pollInterval) throws Exception // NOPMD
{
return doWithTimeout(callable, new SuccessCondition<T>() {
@Override
public boolean success(final T result) {
return result != null;
};
}, timeout, pollInterval);
}
/**
* Call with timeout.
*
* @param callable
* class
* @param successCondition
* class
* @param timeout
* value
* @param pollInterval
* value
* @return
* @throws Exception
*/
public static <T> T doWithTimeout(final Callable<T> callable, final SuccessCondition<T> successCondition,
final long timeout, final long pollInterval) throws Exception // NOPMD
{
if (pollInterval < 0) {
throw new IllegalArgumentException("pollInterval must non negative");
}
long duration = 0;
Exception exception = null;
T returnValue = null;
while (untilTimeoutReached(timeout, duration)) {
try {
returnValue = callable.call();
// clear exception
exception = null;
} catch (final Exception ex) {
exception = ex;
}
Thread.sleep(pollInterval);
duration += pollInterval > 0 ? pollInterval : 1;
if (exception == null && successCondition.success(returnValue)) {
return returnValue;
} else {
returnValue = null;
}
}
if (exception != null) {
throw exception;
}
return returnValue;
}
private static boolean untilTimeoutReached(final long timeout, final long duration) {
return duration <= timeout || timeout < 0;
}
}

View File

@@ -0,0 +1,485 @@
/**
* 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.utils;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.transaction.Transactional;
import org.eclipse.hawkbit.TestDataUtil;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.TagManagement;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
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.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.util.IpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.data.auditing.AuditingHandler;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import net._01001111.text.LoremIpsum;
/**
* Generates test data for setting up the repository for test or demonstration
* purpose.
*
*
*
*/
public final class RepositoryDataGenerator {
private static final Logger LOG = LoggerFactory.getLogger(RepositoryDataGenerator.class);
public static void initDemoRepo(final ConfigurableApplicationContext context) {
final PersistentInitDemoDataBuilder initDemoDataBuilder = new PersistentInitDemoDataBuilder(context);
initDemoDataBuilder.initDemoRepo(20, 0);
}
public static void initLoadRepo(final ConfigurableApplicationContext context) {
final PersistentInitDemoDataBuilder initDemoDataBuilder = new PersistentInitDemoDataBuilder(context);
initDemoDataBuilder.initDemoRepo(200, 200);
}
/**
* builder which build initial demo data and stores it to the repos.
*
*/
private static final class PersistentInitDemoDataBuilder {
private final SoftwareManagement softwareManagement;
private final TargetManagement targetManagement;
private final DeploymentManagement deploymentManagement;
private final TagManagement tagManagement;
private final ControllerManagement controllerManagement;
private final DistributionSetManagement distributionSetManagement;
private final DatabaseCleanupUtil dbCleanupUtil;
private final AuditingHandler auditingHandler;
final LoremIpsum jlorem = new LoremIpsum();
PersistentInitDemoDataBuilder(final ConfigurableApplicationContext context) {
softwareManagement = context.getBean(SoftwareManagement.class);
targetManagement = context.getBean(TargetManagement.class);
tagManagement = context.getBean(TagManagement.class);
deploymentManagement = context.getBean(DeploymentManagement.class);
controllerManagement = context.getBean(ControllerManagement.class);
distributionSetManagement = context.getBean(DistributionSetManagement.class);
dbCleanupUtil = context.getBean(DatabaseCleanupUtil.class);
auditingHandler = context.getBean(AuditingHandler.class);
}
private void runAsAllAuthorityContext(final Runnable runnable) {
final SecurityContext oldContext = SecurityContextHolder.getContext();
try {
final SecurityContextImpl securityContextImpl = new SecurityContextImpl();
final TestingAuthenticationToken authentication = new TestingAuthenticationToken("repogenator",
"repogenator", SpPermission.CREATE_REPOSITORY, SpPermission.CREATE_TARGET,
SpPermission.DELETE_REPOSITORY, SpPermission.DELETE_TARGET, SpPermission.READ_REPOSITORY,
SpPermission.READ_TARGET, SpPermission.UPDATE_REPOSITORY, SpPermission.UPDATE_TARGET,
SpringEvalExpressions.CONTROLLER_ROLE);
securityContextImpl.setAuthentication(authentication);
authentication.setDetails(new TenantAwareAuthenticationDetails("default", false));
SecurityContextHolder.setContext(securityContextImpl);
runnable.run();
} finally {
SecurityContextHolder.setContext(oldContext);
}
}
public void generateTestTagetGroup(final String group, final int sizeMultiplikator) {
final DistributionSetTag dsTag = tagManagement
.createDistributionSetTag(new JpaDistributionSetTag("For " + group + "s"));
auditingHandler.setDateTimeProvider(() -> {
final Calendar instance = Calendar.getInstance();
instance.add(Calendar.MONTH, -new Random().nextInt(7));
return instance;
});
final List<Target> targets = createTargetTestGroup(group, 20 * sizeMultiplikator);
auditingHandler.setDateTimeProvider(() -> {
final Calendar instance = Calendar.getInstance();
return instance;
});
LOG.debug("initDemoRepo - start now real action history for group: {}", group);
// Old history of succesfully finished operations
IntStream.range(0, 10).forEach(idx -> {
final DistributionSet dsReal = TestDataUtil.generateDistributionSet(group + " Release", "v1." + idx,
softwareManagement, distributionSetManagement,
Arrays.asList(new DistributionSetTag[] { dsTag }));
final DistributionSetAssignmentResult result = deploymentManagement.assignDistributionSet(dsReal,
targets);
createSimpleActionStatusHistory(result.getActions());
});
final List<List<Target>> targetGroups = splitIntoGroups(targets);
IntStream.range(0, targetGroups.size()).forEach(idx -> {
final DistributionSet dsReal = TestDataUtil.generateDistributionSet(group + " Release", "v2." + idx,
softwareManagement, distributionSetManagement,
Arrays.asList(new DistributionSetTag[] { dsTag }));
final DistributionSetAssignmentResult result = deploymentManagement.assignDistributionSet(dsReal,
targetGroups.get(idx));
createActionStatusHistory(result.getActions(), sizeMultiplikator);
});
LOG.debug("initDemoRepo - real action history finished for group: {}", group);
}
private List<List<Target>> splitIntoGroups(final List<Target> allTargets) {
final int elements = allTargets.size();
final int group1 = elements * (5 + new Random().nextInt(5)) / 100;
final int group2 = elements * (15 + new Random().nextInt(5)) / 100;
final List<List<Target>> result = new ArrayList<List<Target>>();
result.add(allTargets.subList(0, group1));
result.add(allTargets.subList(group1, group2));
result.add(allTargets.subList(group2, elements));
return result;
}
private void createActionStatusHistory(final List<Long> actions, final int sizeMultiplikator) {
final AtomicInteger counter = new AtomicInteger();
int index = 0;
for (final Long actionGiven : actions) {
// retrieved
Action action = controllerManagement.registerRetrieved(
deploymentManagement.findActionWithDetails(actionGiven),
"Controller retrieved update action and should start now the download.");
// download
final ActionStatus download = new JpaActionStatus();
download.setAction(action);
download.setStatus(Status.DOWNLOAD);
download.addMessage("Controller started download.");
action = controllerManagement.addUpdateActionStatus(download);
// warning
final ActionStatus warning = new JpaActionStatus();
warning.setAction(action);
warning.setStatus(Status.WARNING);
warning.addMessage("Some warning: " + jlorem.words(new Random().nextInt(50)));
action = controllerManagement.addUpdateActionStatus(warning);
// garbage
for (int i = 0; i < new Random().nextInt(10); i++) {
final ActionStatus running = new JpaActionStatus();
running.setAction(action);
running.setStatus(Status.RUNNING);
running.addMessage("Still running: " + jlorem.words(new Random().nextInt(50)));
action = controllerManagement.addUpdateActionStatus(running);
for (int g = 0; g < new Random().nextInt(5); g++) {
final ActionStatus rand = new JpaActionStatus();
rand.setAction(action);
rand.setStatus(Status.RUNNING);
rand.addMessage(jlorem.words(new Random().nextInt(50)));
action = controllerManagement.addUpdateActionStatus(rand);
}
}
// close
final ActionStatus close = new JpaActionStatus();
close.setAction(action);
// with error
final int incrementAndGet = counter.incrementAndGet();
if (incrementAndGet % 5 == 0) {
close.setStatus(Status.ERROR);
close.addMessage("Controller reported CLOSED with ERROR!");
action = controllerManagement.addUpdateActionStatus(close);
}
// with OK
else {
close.setStatus(Status.FINISHED);
close.addMessage("Controller reported CLOSED with OK!");
action = controllerManagement.addUpdateActionStatus(close);
}
index++;
}
}
private void createSimpleActionStatusHistory(final List<Long> actions) {
for (final Long actionGiven : actions) {
// retrieved
Action action = controllerManagement.registerRetrieved(
deploymentManagement.findActionWithDetails(actionGiven),
"Controller retrieved update action and should start now the download.");
// close
final ActionStatus close = new JpaActionStatus();
close.setAction(action);
close.setStatus(Status.FINISHED);
close.addMessage("Controller reported CLOSED with OK!");
action = controllerManagement.addUpdateActionStatus(close);
}
}
private List<Target> createTargetTestGroup(final String group, final int targets) {
LOG.debug("createTargetTestGroup: create group {}", group);
final TargetTag targTag = tagManagement.createTargetTag(new JpaTargetTag(group));
final List<Target> targAs = targetManagement.createTargets(buildTargets(targets, group),
TargetUpdateStatus.REGISTERED, System.currentTimeMillis() - new Random().nextInt(50_000_000),
generateIPAddress());
LOG.debug("createTargetTestGroup: {} created", group);
LOG.debug("createTargetTestGroup: {} targets status updated including IP", group);
return targetManagement.toggleTagAssignment(targAs, targTag).getAssignedEntity();
}
private List<Target> buildTargets(final int noOfTgts, final String descriptionPrefix) {
final List<Target> result = new ArrayList<Target>(noOfTgts);
for (int i = 0; i < noOfTgts; i++) {
final Target target = new JpaTarget(UUID.randomUUID().toString());
final StringBuilder builder = new StringBuilder();
builder.append(descriptionPrefix);
builder.append(jlorem.words(5));
target.setDescription(builder.toString());
target.getTargetInfo().getControllerAttributes().put("revision", "1.1");
target.getTargetInfo().getControllerAttributes().put("capacity", "128M");
target.getTargetInfo().getControllerAttributes().put("serial",
String.valueOf(System.currentTimeMillis()));
result.add(target);
}
return result;
}
/**
* method writes initial test/demo data to the repositories.
*
* @param sizeMultiplikator
* the entire scenario
* @param loadtestgroups
* packages of 1_000 targets
*/
private void initDemoRepo(final int sizeMultiplikator, final int loadtestgroups) {
final LoremIpsum jlorem = new LoremIpsum();
runAsAllAuthorityContext(() -> {
dbCleanupUtil.cleanupDB(null);
// generate targets and assign DS
// 5 groups - 100 targets each -> 500
final String[] targetTestGroups = { "SHC", "CCU", "Vehicle", "Vending machine", "ECU" };
final String[] modulesTypes = { "HeadUnit_FW", "EDC17_FW", "OSGi_Bundle" };
final DistributionSetTag depTag = tagManagement
.createDistributionSetTag(new JpaDistributionSetTag("deprecated"));
Arrays.stream(targetTestGroups).forEach(group -> {
generateTestTagetGroup(group, sizeMultiplikator);
});
// garbage DS
LOG.debug("initDemoRepo - start now DS garbage");
TestDataUtil.generateDistributionSets("Generic Software Package", sizeMultiplikator, softwareManagement,
distributionSetManagement);
LOG.debug("initDemoRepo - DS garbage finished");
LOG.debug("initDemoRepo - start now Extra Software Modules and types");
Arrays.stream(modulesTypes).forEach(typeName -> {
final SoftwareModuleType smtype = softwareManagement.createSoftwareModuleType(
new JpaSoftwareModuleType(typeName.toLowerCase().replaceAll("\\s+", ""), typeName,
jlorem.words(5), Integer.MAX_VALUE));
for (int i1 = 0; i1 < sizeMultiplikator; i1++) {
softwareManagement.createSoftwareModule(new JpaSoftwareModule(smtype, typeName + i1, "1.0." + i1,
jlorem.words(5), "the " + typeName + " vendor Inc."));
}
});
LOG.debug("initDemoRepo - Extra Software Modules and types finished");
LOG.debug("initDemoRepo - start now target garbage");
// garbage targets
// unknown
targetManagement
.createTargets(TestDataUtil.generateTargets(targetTestGroups.length * sizeMultiplikator));
// registered
targetManagement.createTargets(
TestDataUtil.generateTargets(targetTestGroups.length * sizeMultiplikator, "registered"),
TargetUpdateStatus.REGISTERED, System.currentTimeMillis(), generateIPAddress());
// pending
final DistributionSetTag dsTag = tagManagement
.createDistributionSetTag(new JpaDistributionSetTag("OnlyAssignedTag"));
final DistributionSet ds = TestDataUtil.generateDistributionSet("Pending DS", "v1.0",
softwareManagement, distributionSetManagement,
Arrays.asList(new DistributionSetTag[] { dsTag }));
deploymentManagement.assignDistributionSet(ds, targetManagement.createTargets(
TestDataUtil.generateTargets(targetTestGroups.length * sizeMultiplikator, "pending")));
// Load test means additional 1_000_000 target
for (int i2 = 0; i2 < loadtestgroups; i2++) {
targetManagement.createTargets(TestDataUtil.generateTargets(i2 * 1_000, 1_000, "loadtest-"));
}
LOG.debug("initDemoRepo complete");
});
}
/**
* Adding controller attributes for given {@link Target}.
*/
// private Target setControllerAttributes( final String targetId ) {
// final Target target =
// targetManagement.findTargetByControllerIDWithDetails( targetId );
// target.getTargetStatus().getControllerAttributes().put( "revision",
// "1.1" );
// target.getTargetStatus().getControllerAttributes().put( "capacity",
// "128M" );
// target.getTargetStatus().getControllerAttributes().put( "serial",
// String.valueOf(
// System.currentTimeMillis()) );
// return targetManagement.updateTarget( target );
// }
}
/**
*
* Data clean up class.
*
*
*
*/
public static class DatabaseCleanupUtil {
private static final Logger LOG = LoggerFactory.getLogger(DatabaseCleanupUtil.class);
@Autowired
private EntityManager entityManager;
private static final String[] CLEAN_UP_SQLS = new String[] { "sp_tenant", "sp_tenant_configuration",
"sp_artifact", "sp_external_artifact", "sp_external_provider", "sp_target_target_tag",
"sp_target_attributes", "sp_target_tag", "sp_action_status_messages", "sp_action_status", "sp_action",
"sp_ds_dstag", "sp_distributionset_tag", "sp_target_info", "sp_target", "sp_sw_metadata",
"sp_ds_metadata", "sp_ds_module", "sp_distribution_set", "sp_base_software_module",
"sp_ds_type_element", "sp_distribution_set_type", "sp_software_module_type" };
/**
* delete all entries from the DB tables.
*/
@Transactional
@Modifying
public void cleanupDB(final String database) {
LOG.debug("Data clean up is started...");
final boolean isMySql = "MYSQL".equals(database);
if (isMySql) {
// disable foreign key check because otherwise mysql cannot
// delete sp_active_actions due
// the self constraint within the table, stupid MySql
entityManager.createNativeQuery("SET FOREIGN_KEY_CHECKS = 0").executeUpdate();
}
try {
final String[] dbCmds = new String[] { "delete from" };
for (final String dbCmd : dbCmds) {
for (final String table : CLEAN_UP_SQLS) {
final String sql = String.format("%s %s", dbCmd, table);
final Query query = entityManager.createNativeQuery(sql);
try {
LOG.debug("cleanup table: {}", sql);
LOG.debug("cleaned table: {}; deleted {} records", sql, query.executeUpdate());
} catch (final Exception ex) {
LOG.error(String.format("error on executing cleanup statement '%s'", sql), ex);
throw ex;
}
}
}
LOG.debug("Data clean up is finished...");
} finally {
if (isMySql) {
// enable foreign key check again!
entityManager.createNativeQuery("SET FOREIGN_KEY_CHECKS = 1").executeUpdate();
}
}
}
}
/**
* @return a generated IPv4 address string.
*/
private static URI generateIPAddress() {
final Random r = new Random();
return IpUtil
.createHttpUri(r.nextInt(256) + "." + r.nextInt(256) + "." + r.nextInt(256) + "." + r.nextInt(256));
}
private RepositoryDataGenerator() {
super();
}
}

View File

@@ -0,0 +1,27 @@
/**
* 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.utils;
/**
* SuccessCondition Interface.
*
* @param <T>
* type of the value to get verified
*/
public interface SuccessCondition<T> {
/**
* The implementation of the success condition.
*
* @param result
* @return
*/
boolean success(final T result);
}

View File

@@ -0,0 +1,200 @@
/**
* 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.tenancy;
import static org.fest.assertions.api.Assertions.assertThat;
import org.eclipse.hawkbit.AbstractIntegrationTest;
import org.eclipse.hawkbit.WithSpringAuthorityRule;
import org.eclipse.hawkbit.WithUser;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Target;
import org.junit.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Slice;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
/**
* Multi-Tenancy tests which testing the CRUD operations of entities that all
* CRUD-Operations are tenant aware and cannot access or delete entities not
* belonging to the current tenant.
*
*/
@Features("Component Tests - Repository")
@Stories("Multi Tenancy")
public class MultiTenancyEntityTest extends AbstractIntegrationTest {
@Test
@Description(value = "Ensures that multiple targets with same controller-ID can be created for different tenants.")
public void createMultipleTargetsWithSameIdForDifferentTenant() throws Exception {
// known controller ID for overall tenants same
final String knownControllerId = "controllerId";
// known tenant names
final String tenant = "aTenant";
final String anotherTenant = "anotherTenant";
// create targets
createTargetForTenant(knownControllerId, tenant);
createTargetForTenant(knownControllerId, anotherTenant);
// ensure both tenants see their target
final Slice<Target> findTargetsForTenant = findTargetsForTenant(tenant);
assertThat(findTargetsForTenant).hasSize(1);
assertThat(findTargetsForTenant.getContent().get(0).getTenant().toUpperCase()).isEqualTo(tenant.toUpperCase());
final Slice<Target> findTargetsForAnotherTenant = findTargetsForTenant(anotherTenant);
assertThat(findTargetsForAnotherTenant).hasSize(1);
assertThat(findTargetsForAnotherTenant.getContent().get(0).getTenant().toUpperCase())
.isEqualTo(anotherTenant.toUpperCase());
}
@Test
@Description(value = "Ensures that targtes created by a tenant are not visible by another tenant.")
@WithUser(tenantId = "mytenant", allSpPermissions = true)
public void queryTargetFromDifferentTenantIsNotVisible() throws Exception {
// create target for another tenant
final String anotherTenant = "anotherTenant";
final String controllerAnotherTenant = "anotherController";
createTargetForTenant(controllerAnotherTenant, anotherTenant);
// find all targets for current tenant "mytenant"
final Slice<Target> findTargetsAll = targetManagement.findTargetsAll(pageReq);
// no target has been created for "mytenant"
assertThat(findTargetsAll).hasSize(0);
// find all targets for anotherTenant
final Slice<Target> findTargetsForTenant = findTargetsForTenant(anotherTenant);
// another tenant should have targets
assertThat(findTargetsForTenant).hasSize(1);
}
@Test
@Description(value = "Ensures that tenant with proper permissions can read and delete other tenants.")
@WithUser(tenantId = "mytenant", allSpPermissions = true)
public void deleteAnotherTenantPossible() throws Exception {
// create target for another tenant
final String anotherTenant = "anotherTenant";
final String controllerAnotherTenant = "anotherController";
createTargetForTenant(controllerAnotherTenant, anotherTenant);
assertThat(systemManagement.findTenants()).as("Expected number if tenants before deletion is").hasSize(3);
systemManagement.deleteTenant(anotherTenant);
assertThat(systemManagement.findTenants()).as("Expected number if tenants after deletion is").hasSize(2);
}
@Test
@Description(value = "Ensures that tenant metadata is retrieved for the current tenant.")
@WithUser(tenantId = "mytenant", autoCreateTenant = false, allSpPermissions = true)
public void getTenanatMetdata() throws Exception {
// logged in tenant mytenant - check if tenant default data is
// autogenerated
assertThat(distributionSetManagement.findDistributionSetTypesAll(pageReq)).isEmpty();
assertThat(systemManagement.getTenantMetadata().getTenant().toUpperCase()).isEqualTo("mytenant".toUpperCase());
assertThat(distributionSetManagement.findDistributionSetTypesAll(pageReq)).isNotEmpty();
// check that the cache is not getting in the way, i.e. "bumlux" results
// in bumlux and not
// mytenant
assertThat(securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", "bumlux"),
() -> systemManagement.getTenantMetadata().getTenant().toUpperCase()))
.isEqualTo("bumlux".toUpperCase());
}
@Test
@Description(value = "Ensures that targets created from a different tenant cannot be deleted from other tenants")
@WithUser(tenantId = "mytenant", allSpPermissions = true)
public void deleteTargetFromOtherTenantIsNotPossible() throws Exception {
// create target for another tenant
final String anotherTenant = "anotherTenant";
final String controllerAnotherTenant = "anotherController";
final Target createTargetForTenant = createTargetForTenant(controllerAnotherTenant, anotherTenant);
// ensure target cannot be deleted by 'mytenant'
targetManagement.deleteTargets(createTargetForTenant.getId());
Slice<Target> targetsForAnotherTenant = findTargetsForTenant(anotherTenant);
assertThat(targetsForAnotherTenant).hasSize(1);
// ensure another tenant can delete the target
deleteTargetsForTenant(anotherTenant, createTargetForTenant.getId());
targetsForAnotherTenant = findTargetsForTenant(anotherTenant);
assertThat(targetsForAnotherTenant).hasSize(0);
}
@Test
@Description(value = "Ensures that multiple distribution sets with same name and version can be created for different tenants.")
public void createMultipleDistributionSetsWithSameNameForDifferentTenants() throws Exception {
// known ds name for overall tenants same
final String knownDistributionSetName = "dsName";
final String knownDistributionSetVersion = "0.0.0";
// known tenant names
final String tenant = "aTenant";
final String anotherTenant = "anotherTenant";
// create distribution sets
createDistributionSetForTenant(knownDistributionSetName, knownDistributionSetVersion, tenant);
createDistributionSetForTenant(knownDistributionSetName, knownDistributionSetVersion, anotherTenant);
// ensure both tenants see their distribution sets
final Page<DistributionSet> findDistributionSetsForTenant = findDistributionSetForTenant(tenant);
assertThat(findDistributionSetsForTenant).hasSize(1);
assertThat(findDistributionSetsForTenant.getContent().get(0).getTenant().toUpperCase())
.isEqualTo(tenant.toUpperCase());
final Page<DistributionSet> findDistributionSetsForAnotherTenant = findDistributionSetForTenant(anotherTenant);
assertThat(findDistributionSetsForAnotherTenant).hasSize(1);
assertThat(findDistributionSetsForAnotherTenant.getContent().get(0).getTenant().toUpperCase())
.isEqualTo(anotherTenant.toUpperCase());
}
private Target createTargetForTenant(final String controllerId, final String tenant) throws Exception {
return securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant),
() -> targetManagement.createTarget(new JpaTarget(controllerId)));
}
private Slice<Target> findTargetsForTenant(final String tenant) throws Exception {
return securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant),
() -> targetManagement.findTargetsAll(pageReq));
}
private void deleteTargetsForTenant(final String tenant, final Long... targetIds) throws Exception {
securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant), () -> {
targetManagement.deleteTargets(targetIds);
return null;
});
}
private DistributionSet createDistributionSetForTenant(final String name, final String version, final String tenant)
throws Exception {
return securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant), () -> {
final JpaDistributionSet ds = new JpaDistributionSet();
ds.setName(name);
ds.setTenant(tenant);
ds.setVersion(version);
ds.setType(distributionSetManagement
.createDistributionSetType(new JpaDistributionSetType("typetest", "test", "foobar")));
return distributionSetManagement.createDistributionSet(ds);
});
}
private Page<DistributionSet> findDistributionSetForTenant(final String tenant) throws Exception {
return securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant),
() -> distributionSetManagement.findDistributionSetsByDeletedAndOrCompleted(pageReq, false, false));
}
}

View File

@@ -0,0 +1,34 @@
#
# 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
#
spring.data.mongodb.uri=mongodb://localhost/spArtifactRepository${random.value}
spring.data.mongodb.port=28017
hawkbit.server.ddi.security.authentication.header.enabled=true
hawkbit.server.ddi.security.authentication.gatewaytoken.name=TestToken
multipart.max-file-size=5MB
hawkbit.server.security.dos.maxStatusEntriesPerAction=100
hawkbit.server.security.dos.maxAttributeEntriesPerTarget=10
spring.jpa.database=H2
spring.datasource.url=jdbc:h2:mem:sp-db;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=sa
flyway.enabled=true
flyway.sqlMigrationSuffix=${spring.jpa.database}.sql
#spring.jpa.show-sql=true
# DDI configuration
hawkbit.controller.pollingTime=00:01:00
hawkbit.controller.pollingOverdueTime=00:01:00