Skip to content

Commit

Permalink
Merge pull request #34 from devatherock/unit-tests
Browse files Browse the repository at this point in the history
Unit tests for custom badge generation - connects to #24
  • Loading branch information
devatherock authored Nov 16, 2020
2 parents e6ad368 + 7fc5a62 commit 4213ab9
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 27 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ docker run --rm \
<rect width="144" height="20" fill="url(#s)"/>
</g>
<g font-family="monospace">
<text aria-hidden="true" x="0" y="15" fill="#fff" xml:space="preserve">docker pulls</text>
<text aria-hidden="true" x="112" y="15" fill="#fff" xml:space="preserve">47</text>
<text aria-hidden="true" x="0" y="15" fill="#fff" xml:space="preserve"> docker pulls </text>
<text aria-hidden="true" x="112" y="15" fill="#fff" xml:space="preserve"> 47 </text>
</g>
</svg>
```
Expand Down
12 changes: 3 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,10 @@ ext.jacoco = [
// Should be removed when all tests have been written
coverageThresholds: [
'io.github.devatherock.artifactory.service.DockerBadgeService': [
'BRANCH': 0.57,
'COMPLEXITY': 0.48,
'INSTRUCTION': 0.91,
'LINE': 0.90
],
'io.github.devatherock.artifactory.util.BadgeGenerator': [
'BRANCH': 0.50,
'BRANCH': 0.66,
'COMPLEXITY': 0.50,
'INSTRUCTION': 0.10,
'LINE': 0.14
'INSTRUCTION': 0.93,
'LINE': 0.90
]
]
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
import java.util.Map;
import java.util.regex.Pattern;

/**
* Service class to fetch information required for the badges and then generate
* them
*
* @author devaprasadh
*
*/
@Slf4j
@Blocking
@Singleton
Expand Down Expand Up @@ -56,7 +63,6 @@ public class DockerBadgeService {
private final BadgeGenerator badgeGenerator;
private final ArtifactoryProperties artifactoryConfig;


@Cacheable(cacheNames = "size-cache")
public String getImageSizeBadge(String packageName, String tag, String badgeLabel) {
LOGGER.debug("In getImageSizeBadge");
Expand All @@ -70,8 +76,7 @@ public String getImageSizeBadge(String packageName, String tag, String badgeLabe
.get() / BYTES_IN_MB;

LOGGER.info("Size of {}/{}: {} MB", packageName, tag, imageSize);
return badgeGenerator.generateBadge(badgeLabel, String.format("%s MB",
formatDecimal(imageSize, "0.##")));
return badgeGenerator.generateBadge(badgeLabel, String.format("%s MB", formatDecimal(imageSize, "0.##")));
} else {
return generateNotFoundBadge(badgeLabel);
}
Expand Down Expand Up @@ -100,11 +105,13 @@ public String getPullsCountBadge(String packageName, String badgeLabel) {

for (ArtifactoryFolderElement child : folderInfo.getChildren()) {
if (child.isFolder()) {
HttpRequest<Object> fileRequest = HttpRequest.create(HttpMethod.GET,
artifactoryConfig.getStorageUrlPrefix() + packageName
+ child.getUri() + FILE_NAME_MANIFEST + "?stats")
HttpRequest<Object> fileRequest = HttpRequest
.create(HttpMethod.GET,
artifactoryConfig.getStorageUrlPrefix() + packageName + child.getUri()
+ FILE_NAME_MANIFEST + "?stats")
.header(HDR_API_KEY, artifactoryConfig.getApiKey());
ArtifactoryFileStats fileStats = artifactoryClient.retrieve(fileRequest, ArtifactoryFileStats.class);
ArtifactoryFileStats fileStats = artifactoryClient.retrieve(fileRequest,
ArtifactoryFileStats.class);

if (null != fileStats) {
downloadCount += fileStats.getDownloadCount();
Expand All @@ -130,14 +137,15 @@ public String getLatestVersionBadge(String packageName, String badgeLabel) {
if (child.isFolder()) {
ArtifactoryFolderInfo currentVersion = getArtifactoryFolderInfo(packageName + child.getUri());

if (null == latestVersion || Instant.from(MODIFIED_TIME_PARSER.parse(currentVersion.getLastModified()))
.compareTo(Instant.from(MODIFIED_TIME_PARSER.parse(latestVersion.getLastModified()))) > 0) {
if (null == latestVersion
|| Instant.from(MODIFIED_TIME_PARSER.parse(currentVersion.getLastModified())).compareTo(
Instant.from(MODIFIED_TIME_PARSER.parse(latestVersion.getLastModified()))) > 0) {
latestVersion = currentVersion;
}
}
}

if(null != latestVersion) {
if (null != latestVersion) {
LOGGER.info("Latest version of {}: {}", packageName, latestVersion.getPath());
return badgeGenerator.generateBadge(badgeLabel, getVersionBadgeValue(latestVersion));
} else {
Expand All @@ -155,8 +163,9 @@ public String getLatestVersionBadge(String packageName, String badgeLabel) {
* @return {@link ArtifactoryFolderInfo}
*/
private ArtifactoryFolderInfo getArtifactoryFolderInfo(String packageName) {
HttpRequest<Object> folderRequest = HttpRequest.create(HttpMethod.GET, artifactoryConfig.getStorageUrlPrefix()
+ packageName).header(HDR_API_KEY, artifactoryConfig.getApiKey());
HttpRequest<Object> folderRequest = HttpRequest
.create(HttpMethod.GET, artifactoryConfig.getStorageUrlPrefix() + packageName)
.header(HDR_API_KEY, artifactoryConfig.getApiKey());
return artifactoryClient.retrieve(folderRequest, ArtifactoryFolderInfo.class);
}

Expand All @@ -179,8 +188,9 @@ private String generateNotFoundBadge(String badgeLabel) {
*/
private DockerManifest readManifest(String packageName, String tag) {
String fullPackageName = packageName + "/" + tag;
HttpRequest<Object> manifestRequest = HttpRequest.create(HttpMethod.GET, artifactoryConfig.getUrlPrefix()
+ fullPackageName + FILE_NAME_MANIFEST).header(HDR_API_KEY, artifactoryConfig.getApiKey());
HttpRequest<Object> manifestRequest = HttpRequest
.create(HttpMethod.GET, artifactoryConfig.getUrlPrefix() + fullPackageName + FILE_NAME_MANIFEST)
.header(HDR_API_KEY, artifactoryConfig.getApiKey());
return artifactoryClient.retrieve(manifestRequest, DockerManifest.class);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@
import io.github.devatherock.artifactory.config.ShieldsIOProperties;
import io.github.devatherock.artifactory.service.ShieldsIOClient;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import javax.inject.Singleton;

/**
* Class to generate the badges
*
* @author devaprasadh
*
*/
@Slf4j
@Singleton
@RequiredArgsConstructor
Expand All @@ -17,7 +22,6 @@ public class BadgeGenerator {
private final ShieldsIOClient shieldsIOClient;
private final ShieldsIOProperties config;

@SneakyThrows
public String generateBadge(String label, String value) {
LOGGER.debug("In generateBadge");
String badge = null;
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/graal/access-filter.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
{"excludeClasses": "io.github.devatherock.artifactory.controllers.VersionControllerSpec"},
{"excludeClasses": "io.github.devatherock.artifactory.config.AppConfigSpec"},
{"excludeClasses": "io.github.devatherock.artifactory.config.ArtifactoryPropertiesSpec"},
{"excludeClasses": "io.github.devatherock.artifactory.util.BadgeGeneratorSpec"},
{"excludeClasses": "io.github.devatherock.artifactory.service.DockerBadgeServiceSpec"},
{"excludeClasses": "org.spockframework.**"},
{"excludeClasses": "org.gradle.**"},
{"excludeClasses": "net.sf.cglib.**"},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.github.devatherock.artifactory.service

import io.github.devatherock.artifactory.config.ArtifactoryProperties
import io.github.devatherock.artifactory.entities.ArtifactoryFolderInfo
import io.github.devatherock.artifactory.util.BadgeGenerator
import io.micronaut.http.client.BlockingHttpClient
import io.micronaut.http.client.HttpClient
import spock.lang.Specification
import spock.lang.Subject

/**
* Test class for {@link DockerBadgeService}
*/
class DockerBadgeServiceSpec extends Specification {
@Subject
DockerBadgeService dockerBadgeService

BlockingHttpClient httpClient = HttpClient.create(new URL('http://localhost:8081')).toBlocking()
BadgeGenerator badgeGenerator = Mock()
ArtifactoryProperties config = new ArtifactoryProperties(url: 'http://localhost:8081')

void setup() {
config.init()
dockerBadgeService = new DockerBadgeService(httpClient, badgeGenerator, config)
}

void 'test get version badge value'() {
expect:
dockerBadgeService.getVersionBadgeValue(new ArtifactoryFolderInfo(path: path)) == outputVersion

where:
path | outputVersion
'docker/devatherock/simple-slack/1.1.0' | 'v1.1.0'
'docker/devatherock/simple-slack/latest' | 'latest'
}

void 'test format download count'() {
expect:
dockerBadgeService.formatDownloadCount(downloadCount) == formattedCount

where:
downloadCount | formattedCount
450 | '450'
1249 | '1.2k'
1251 | '1.3k'
1_100_000 | '1.1M'
1_100_000_000 | '1.1G'
1_100_000_000_000 | '1100G'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package io.github.devatherock.artifactory.util

import io.github.devatherock.artifactory.config.ShieldsIOProperties
import io.github.devatherock.artifactory.service.ShieldsIOClient
import spock.lang.Specification
import spock.lang.Subject

/**
* Test class for {@link BadgeGenerator}
*/
class BadgeGeneratorSpec extends Specification {
@Subject
BadgeGenerator badgeGenerator

ShieldsIOClient shieldsIOClient = Mock()
ShieldsIOProperties config = new ShieldsIOProperties(enabled: false)

void setup() {
badgeGenerator = new BadgeGenerator(shieldsIOClient, config)
}

void 'test generate badge - custom generator'() {
given:
String expectedResponse = [
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="144" height="20" role="img" aria-label="docker pulls: 47">',
'<title>docker pulls: 47</title>',
'<linearGradient id="s" x2="0" y2="100%">',
'<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>',
'<stop offset="1" stop-opacity=".1"/>',
'</linearGradient>',
'<clipPath id="r">',
'<rect width="144" height="20" rx="3" fill="#fff"/>',
'</clipPath>',
'<g clip-path="url(#r)">',
'<rect width="112" height="20" fill="#555"/>',
'<rect x="112" width="32" height="20" fill="#007ec6"/>',
'<rect width="144" height="20" fill="url(#s)"/>',
'</g>',
'<g font-family="monospace">',
'<text aria-hidden="true" x="0" y="15" fill="#fff" xml:space="preserve"> docker pulls </text>',
'<text aria-hidden="true" x="112" y="15" fill="#fff" xml:space="preserve"> 47 </text>',
'</g>',
'</svg>'
].join('')

when:
String badge = badgeGenerator.generateBadge('docker pulls', '47')

then:
badge == expectedResponse
}
}

0 comments on commit 4213ab9

Please sign in to comment.