Skip to content

Commit

Permalink
Merge pull request #32 from devatherock/24-unit-tests
Browse files Browse the repository at this point in the history
Added more unit tests - connects to #24
  • Loading branch information
devatherock authored Nov 15, 2020
2 parents a124289 + 22b7190 commit 7406853
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 21 deletions.
22 changes: 18 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id "net.ltgt.apt-eclipse" version "0.21"
id "com.github.johnrengelman.shadow" version "5.0.0"
id "application"
id 'java'
id 'groovy'
id 'jacoco'
id 'org.sonarqube' version '3.0'
Expand Down Expand Up @@ -57,6 +58,7 @@ dependencies {
testImplementation group: 'org.spockframework', name: 'spock-core', version: '1.3-groovy-2.5'
testImplementation group: 'cglib', name: 'cglib-nodep', version: '3.3.0'
testImplementation group: 'org.objenesis', name: 'objenesis', version: '3.1'
testImplementation group: 'com.github.tomakehurst', name: 'wiremock', version: '2.27.2'
}

test.classpath += configurations.developmentOnly
Expand Down Expand Up @@ -87,10 +89,22 @@ run {
ext.jacoco = [
exclusions: [
'io/github/devatherock/Application.class',
'io/github/devatherock/test/ArtifactoryController.class',
// Excluded for now till tests are written
'io/github/devatherock/artifactory/service/DockerBadgeService.class',
'io/github/devatherock/artifactory/util/BadgeGenerator.class'
'io/github/devatherock/test/ArtifactoryController.class'
],
// Should be removed when all tests have been written
coverageThresholds: [
'io.github.devatherock.artifactory.service.DockerBadgeService': [
'BRANCH': 0.28,
'COMPLEXITY': 0.32,
'INSTRUCTION': 0.70,
'LINE': 0.70
],
'io.github.devatherock.artifactory.util.BadgeGenerator': [
'BRANCH': 0.50,
'COMPLEXITY': 0.50,
'INSTRUCTION': 0.10,
'LINE': 0.14
]
]
]
apply from: '../gradle-includes/checks.gradle'
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import io.micronaut.http.annotation.QueryValue;
import io.micronaut.http.client.annotation.Client;

@Client(value = "https://img.shields.io")
@Client(value = "${artifactory.badge.shields-io.url}")
public interface ShieldsIOClient {

@Get(value = "/static/v1")
Expand Down
6 changes: 5 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,8 @@ micronaut:
mapping: /swagger/**
swagger-ui:
paths: classpath:META-INF/swagger/views/swagger-ui
mapping: /swagger-ui/**
mapping: /swagger-ui/**
artifactory:
badge:
shields-io:
url: https://img.shields.io
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class AppConfigSpec extends Specification {
@Subject
AppConfig appConfig = new AppConfig()

def 'test initialize http client'() {
void 'test initialize http client'() {
given:
HttpClient httpClient = Mock()
BlockingHttpClient outputClient = Mock()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,76 +1,141 @@
package io.github.devatherock.artifactory.controllers

import io.github.devatherock.artifactory.service.DockerBadgeService
import com.github.tomakehurst.wiremock.WireMockServer
import com.github.tomakehurst.wiremock.client.WireMock
import io.micronaut.http.HttpRequest
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.annotation.Client
import io.micronaut.http.uri.UriBuilder
import io.micronaut.test.annotation.MockBean
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import spock.lang.Shared
import spock.lang.Specification

import javax.inject.Inject

import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;

/**
* Test class for {@link DockerController}
*/
@MicronautTest(propertySources = 'classpath:application-test.yml')
class DockerControllerSpec extends Specification {

@Inject
DockerBadgeService badgeService
@Shared
WireMockServer mockServer = new WireMockServer(8081)

@Inject
@Client('/')
HttpClient httpClient

void setupSpec() {
WireMock.configureFor(8081)
mockServer.start()
}

void cleanupSpec() {
mockServer.stop()
}

void cleanup() {
mockServer.resetRequests()
}

void 'test get image pull count - default label'() {
given:
String packageName = 'docker/devatherock/simple-slack'

and:
WireMock.givenThat(WireMock.get("/artifactory/api/storage/${packageName}")
.willReturn(WireMock.okJson(getFoldersResponse())))
WireMock.givenThat(WireMock.get("/artifactory/api/storage/${packageName}/1.1.0/manifest.json?stats")
.willReturn(WireMock.okJson(getManifestStats('1.1.0', 10))))
WireMock.givenThat(WireMock.get("/artifactory/api/storage/${packageName}/1.1.2/manifest.json?stats")
.willReturn(WireMock.okJson(getManifestStats('1.1.2', 20))))
WireMock.givenThat(WireMock.get("/artifactory/api/storage/${packageName}/latest/manifest.json?stats")
.willReturn(WireMock.okJson(getManifestStats('latest', 30))))
WireMock.givenThat(WireMock.get("/artifactory/api/storage/${packageName}/abcdefgh/manifest.json?stats")
.willReturn(WireMock.okJson(getManifestStats('abcdefgh', 40))))
WireMock.givenThat(WireMock.get(WireMock.urlPathEqualTo('/static/v1'))
.withQueryParam('label', equalTo('docker pulls'))
.withQueryParam('message', equalTo('100'))
.withQueryParam('color', equalTo('blue'))
.willReturn(WireMock.okXml('dummyBadge')))

when:
String badge = httpClient.toBlocking().retrieve(
HttpRequest.GET(UriBuilder.of('/docker/pulls')
.queryParam('package', packageName).build()))

then:
1 * badgeService.getPullsCountBadge(packageName, 'docker pulls') >> 'dummyBadge'
badge == 'dummyBadge'
}

void 'test get image pull count - custom label'() {
given:
String packageName = 'docker/devatherock/simple-slack'

and:
WireMock.givenThat(WireMock.get("/artifactory/api/storage/${packageName}")
.willReturn(WireMock.okJson(getFoldersResponse())))
WireMock.givenThat(WireMock.get("/artifactory/api/storage/${packageName}/1.1.0/manifest.json?stats")
.willReturn(WireMock.okJson(getManifestStats('1.1.0', 10))))
WireMock.givenThat(WireMock.get("/artifactory/api/storage/${packageName}/1.1.2/manifest.json?stats")
.willReturn(WireMock.okJson(getManifestStats('1.1.2', 20))))
WireMock.givenThat(WireMock.get("/artifactory/api/storage/${packageName}/latest/manifest.json?stats")
.willReturn(WireMock.okJson(getManifestStats('latest', 30))))
WireMock.givenThat(WireMock.get("/artifactory/api/storage/${packageName}/abcdefgh/manifest.json?stats")
.willReturn(WireMock.okJson(getManifestStats('abcdefgh', 40))))
WireMock.givenThat(WireMock.get(WireMock.urlPathEqualTo('/static/v1'))
.withQueryParam('label', equalTo('downloads'))
.withQueryParam('message', equalTo('100'))
.withQueryParam('color', equalTo('blue'))
.willReturn(WireMock.okXml('dummyBadge')))

when:
String badge = httpClient.toBlocking().retrieve(
HttpRequest.GET(UriBuilder.of('/docker/pulls')
.queryParam('package', packageName)
.queryParam('label', 'downloads').build()))

then:
1 * badgeService.getPullsCountBadge(packageName, 'downloads') >> 'dummyBadge'
badge == 'dummyBadge'
}

void 'test get image size - default label and tag'() {
given:
String packageName = 'docker/devatherock/simple-slack'

and:
WireMock.givenThat(WireMock.get("/artifactory/${packageName}/latest/manifest.json")
.willReturn(WireMock.okJson(getManifest())))
WireMock.givenThat(WireMock.get(WireMock.urlPathEqualTo('/static/v1'))
.withQueryParam('label', equalTo('image size'))
.withQueryParam('message', equalTo('11 MB'))
.withQueryParam('color', equalTo('blue'))
.willReturn(WireMock.okXml('dummyBadge')))

when:
String badge = httpClient.toBlocking().retrieve(
HttpRequest.GET(UriBuilder.of('/docker/image-size')
.queryParam('package', packageName).build()))

then:
1 * badgeService.getImageSizeBadge(packageName, 'latest', 'image size') >> 'dummyBadge'
badge == 'dummyBadge'
}

void 'test get image size - custom label and tag'() {
given:
String packageName = 'docker/devatherock/simple-slack'

and:
WireMock.givenThat(WireMock.get("/artifactory/${packageName}/1.2.0/manifest.json")
.willReturn(WireMock.okJson(getManifest())))
WireMock.givenThat(WireMock.get(WireMock.urlPathEqualTo('/static/v1'))
.withQueryParam('label', equalTo('size'))
.withQueryParam('message', equalTo('11 MB'))
.withQueryParam('color', equalTo('blue'))
.willReturn(WireMock.okXml('dummyBadge')))

when:
String badge = httpClient.toBlocking().retrieve(
HttpRequest.GET(UriBuilder.of('/docker/image-size')
Expand All @@ -79,28 +144,44 @@ class DockerControllerSpec extends Specification {
.queryParam('label', 'size').build()))

then:
1 * badgeService.getImageSizeBadge(packageName, '1.2.0', 'size') >> 'dummyBadge'
badge == 'dummyBadge'
}

void 'test get layers - default label and tag'() {
given:
String packageName = 'docker/devatherock/simple-slack'

and:
WireMock.givenThat(WireMock.get("/artifactory/${packageName}/latest/manifest.json")
.willReturn(WireMock.okJson(getManifest())))
WireMock.givenThat(WireMock.get(WireMock.urlPathEqualTo('/static/v1'))
.withQueryParam('label', equalTo('layers'))
.withQueryParam('message', equalTo('2'))
.withQueryParam('color', equalTo('blue'))
.willReturn(WireMock.okXml('dummyBadge')))

when:
String badge = httpClient.toBlocking().retrieve(
HttpRequest.GET(UriBuilder.of('/docker/layers')
.queryParam('package', packageName).build()))

then:
1 * badgeService.getImageLayersBadge(packageName, 'latest', 'layers') >> 'dummyBadge'
badge == 'dummyBadge'
}

void 'test get layers - custom label and tag'() {
given:
String packageName = 'docker/devatherock/simple-slack'

and:
WireMock.givenThat(WireMock.get("/artifactory/${packageName}/1.2.0/manifest.json")
.willReturn(WireMock.okJson(getManifest())))
WireMock.givenThat(WireMock.get(WireMock.urlPathEqualTo('/static/v1'))
.withQueryParam('label', equalTo('number of layers'))
.withQueryParam('message', equalTo('2'))
.withQueryParam('color', equalTo('blue'))
.willReturn(WireMock.okXml('dummyBadge')))

when:
String badge = httpClient.toBlocking().retrieve(
HttpRequest.GET(UriBuilder.of('/docker/layers')
Expand All @@ -109,12 +190,72 @@ class DockerControllerSpec extends Specification {
.queryParam('label', 'number of layers').build()))

then:
1 * badgeService.getImageLayersBadge(packageName, '1.2.0', 'number of layers') >> 'dummyBadge'
badge == 'dummyBadge'
}

@MockBean(DockerBadgeService)
DockerBadgeService badgeService() {
Mock(DockerBadgeService)
String getFoldersResponse() {
"""{
"repo": "docker",
"path": "/devatherock/simple-slack",
"created": "2018-09-23T18:02:56.147Z",
"createdBy": "devatherock",
"lastModified": "2018-09-23T18:02:56.147Z",
"modifiedBy": "devatherock",
"lastUpdated": "2018-09-23T18:02:56.147Z",
"children": [
{
"uri": "/1.1.0",
"folder": true
},
{
"uri": "/1.1.2",
"folder": true
},
{
"uri": "/latest",
"folder": true
},
{
"uri": "/abcdefgh",
"folder": true
}
],
"uri": "http://localhost:8081/artifactory/api/storage/docker/devatherock/simple-slack"
}"""
}

String getManifestStats(String tag, int downloadCount) {
"""{
"uri": "http://localhost:8081/artifactory/docker/devatherock/simple-slack/${tag}/manifest.json",
"downloadCount": ${downloadCount},
"lastDownloaded": 1602863958001,
"lastDownloadedBy": "devatherock",
"remoteDownloadCount": 0,
"remoteLastDownloaded": 0
}"""
}

String getManifest() {
"""{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 3027,
"digest": "sha256:9fe1c24da9391a4d7346200a997c06c7c900466181081af7953a2a15c9fffd7c"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 10485760,
"digest": "sha256:e7c96db7181be991f19a9fb6975cdbbd73c65f4a2681348e63a141a2192a5f10"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 1048576,
"digest": "sha256:f910a506b6cb1dbec766725d70356f695ae2bf2bea6224dbe8c7c6ad4f3664a2"
}
]
}"""
}
}
5 changes: 4 additions & 1 deletion src/test/resources/application-test.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
artifactory:
url: http://localhost:8081
api-key: dummyKey
api-key: dummyKey
badge:
shields-io:
url: http://localhost:8081

0 comments on commit 7406853

Please sign in to comment.