Tests for referenced images and system image names
This commit is contained in:
parent
e1ceacedca
commit
d06cfa9ae0
@ -19,19 +19,24 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
|||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import com.google.common.hash.Hashing;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.thingsboard.common.util.JacksonUtil;
|
import org.thingsboard.common.util.JacksonUtil;
|
||||||
import org.thingsboard.server.common.data.util.MediaTypeUtils;
|
import org.thingsboard.server.common.data.util.MediaTypeUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class SystemImagesMigrator { // TEMPORARY
|
public class SystemImagesMigrator { // TEMPORARY
|
||||||
@ -45,6 +50,7 @@ public class SystemImagesMigrator { // TEMPORARY
|
|||||||
private static final Path demoDashboardsDir = dataDir.resolve("json").resolve("demo").resolve("dashboards");
|
private static final Path demoDashboardsDir = dataDir.resolve("json").resolve("demo").resolve("dashboards");
|
||||||
|
|
||||||
private static final Map<String, String> imageNames = new TreeMap<>();
|
private static final Map<String, String> imageNames = new TreeMap<>();
|
||||||
|
private static final Map<String, String> imageHashes = new HashMap<>();
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
Files.createDirectories(imagesDir);
|
Files.createDirectories(imagesDir);
|
||||||
@ -196,6 +202,32 @@ public class SystemImagesMigrator { // TEMPORARY
|
|||||||
return "/api/images/system/" + imageKey;
|
return "/api/images/system/" + imageKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void checkDuplicates() throws IOException {
|
||||||
|
Files.walk(imagesDir)
|
||||||
|
.filter(path -> path.toFile().isFile())
|
||||||
|
.filter(path -> !path.getFileName().toString().endsWith("json"))
|
||||||
|
.forEach(imageFile -> {
|
||||||
|
try {
|
||||||
|
byte[] data = Files.readAllBytes(imageFile);
|
||||||
|
String hash = Hashing.sha256().hashBytes(data).toString();
|
||||||
|
imageHashes.put(imageFile.getFileName().toString(), hash);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
imageHashes.values().stream()
|
||||||
|
.distinct()
|
||||||
|
.forEach(hash -> {
|
||||||
|
List<String> sameImages = imageHashes.entrySet().stream()
|
||||||
|
.filter(entry -> entry.getValue().equals(hash))
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (sameImages.size() > 1) {
|
||||||
|
System.err.println("Duplicated images (hash " + hash + "):\n" + String.join("\n", sameImages) + "\n");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static String getText(JsonNode jsonNode, String field) {
|
private static String getText(JsonNode jsonNode, String field) {
|
||||||
return Optional.ofNullable(jsonNode.get(field))
|
return Optional.ofNullable(jsonNode.get(field))
|
||||||
.filter(JsonNode::isTextual)
|
.filter(JsonNode::isTextual)
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.service.install;
|
package org.thingsboard.server.service.install;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
@ -36,12 +37,19 @@ import org.thingsboard.server.dao.tenant.TenantService;
|
|||||||
import org.thingsboard.server.dao.usagerecord.ApiLimitService;
|
import org.thingsboard.server.dao.usagerecord.ApiLimitService;
|
||||||
import org.thingsboard.server.dao.widget.WidgetTypeService;
|
import org.thingsboard.server.dao.widget.WidgetTypeService;
|
||||||
import org.thingsboard.server.dao.widget.WidgetsBundleService;
|
import org.thingsboard.server.dao.widget.WidgetsBundleService;
|
||||||
|
import org.thingsboard.server.service.install.update.ImagesUpdater;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
@ -63,6 +71,8 @@ class InstallScriptsTest {
|
|||||||
OAuth2ConfigTemplateService oAuth2TemplateService;
|
OAuth2ConfigTemplateService oAuth2TemplateService;
|
||||||
@MockBean
|
@MockBean
|
||||||
ResourceService resourceService;
|
ResourceService resourceService;
|
||||||
|
@MockBean
|
||||||
|
ImagesUpdater imagesUpdater;
|
||||||
@SpyBean
|
@SpyBean
|
||||||
InstallScripts installScripts;
|
InstallScripts installScripts;
|
||||||
|
|
||||||
@ -116,4 +126,49 @@ class InstallScriptsTest {
|
|||||||
.containsExactlyInAnyOrderElementsOf(Collections.emptyList());
|
.containsExactlyInAnyOrderElementsOf(Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSystemImageNames() throws IOException {
|
||||||
|
Path imagesDir = Path.of(installScripts.getDataDir(), InstallScripts.IMAGES_DIR);
|
||||||
|
Path imageNamesFile = imagesDir.resolve("names.json");
|
||||||
|
Map<String, String> imageNames = JacksonUtil.OBJECT_MAPPER.readValue(imageNamesFile.toFile(), new TypeReference<>() {});
|
||||||
|
|
||||||
|
assertThat(imageNames.keySet()).containsAll(getSystemImages());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReferencedImages() throws IOException {
|
||||||
|
Path jsonDir = Path.of(installScripts.getDataDir(), InstallScripts.JSON_DIR);
|
||||||
|
List<Path> files = Files.walk(jsonDir)
|
||||||
|
.filter(path -> path.toFile().isFile())
|
||||||
|
.filter(path -> path.getFileName().toString().endsWith(".json"))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
Set<String> referencedImages = new HashSet<>();
|
||||||
|
Pattern imageUrlPattern = Pattern.compile("/api/images/system/(.+?)\\\\?\"");
|
||||||
|
for (Path file : files) {
|
||||||
|
String content = Files.readString(file);
|
||||||
|
imageUrlPattern.matcher(content).results()
|
||||||
|
.map(matchResult -> matchResult.group(1))
|
||||||
|
.forEach(referencedImages::add);
|
||||||
|
}
|
||||||
|
assertThat(getSystemImages()).containsAll(referencedImages);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> getSystemImages() throws IOException {
|
||||||
|
String dataDir = installScripts.getDataDir();
|
||||||
|
Path imagesDir = Path.of(dataDir, InstallScripts.IMAGES_DIR);
|
||||||
|
|
||||||
|
return Files.list(imagesDir)
|
||||||
|
.filter(path -> path.toFile().isDirectory())
|
||||||
|
.flatMap(dir -> {
|
||||||
|
try {
|
||||||
|
return Files.list(dir);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map(path -> path.getFileName().toString())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user