Perform candidate cache check in main function.

This commit is contained in:
Marco Vermeulen
2017-12-05 08:47:23 +00:00
parent 6836ecf170
commit c438dfef3e
14 changed files with 133 additions and 203 deletions

View File

@@ -98,25 +98,6 @@ fi
if [[ -z "$sdkman_curl_connect_timeout" ]]; then sdkman_curl_connect_timeout=7; fi
if [[ -z "$sdkman_curl_max_time" ]]; then sdkman_curl_max_time=10; fi
# fabricate list of candidates
SDKMAN_CANDIDATES_CACHE="${SDKMAN_DIR}/var/candidates"
if [[ -f "$SDKMAN_CANDIDATES_CACHE" && -n "$(cat "$SDKMAN_CANDIDATES_CACHE")" && -z "$(find "$SDKMAN_CANDIDATES_CACHE" -mmin +$((60*24)))" ]]; then
__sdkman_echo_debug "Using existing candidates cache: $SDKMAN_CANDIDATES_CACHE"
else
CANDIDATES_URI="${SDKMAN_CURRENT_API}/candidates/all"
__sdkman_echo_debug "Using candidates endpoint: $CANDIDATES_URI"
SDKMAN_FRESH_CANDIDATES_CSV=$(__sdkman_secure_curl_with_timeouts "$CANDIDATES_URI")
__sdkman_echo_debug "Fetched candidates csv: $SDKMAN_FRESH_CANDIDATES_CSV"
DETECT_HTML="$(echo "$SDKMAN_FRESH_CANDIDATES_CSV" | tr '[:upper:]' '[:lower:]' | grep 'html')"
if [[ -n "$SDKMAN_FRESH_CANDIDATES_CSV" && -z "$DETECT_HTML" ]]; then
__sdkman_echo_debug "Overwriting candidates cache with: $SDKMAN_FRESH_CANDIDATES_CSV"
echo "$SDKMAN_FRESH_CANDIDATES_CSV" > "$SDKMAN_CANDIDATES_CACHE"
fi
unset CANDIDATES_URI SDKMAN_FRESH_CANDIDATES_CSV DETECT_HTML
fi
SDKMAN_CANDIDATES_CSV=$(cat "$SDKMAN_CANDIDATES_CACHE")
# determine if up to date
SDKMAN_VERSION_FILE="${SDKMAN_DIR}/var/version"
if [[ "$sdkman_beta_channel" != "true" && -f "$SDKMAN_VERSION_FILE" && -z "$(find "$SDKMAN_VERSION_FILE" -mmin +$((60*24)))" ]]; then
@@ -144,7 +125,10 @@ else
fi
fi
# Set the candidate array
# Read list of candidates and set array
SDKMAN_CANDIDATES_CACHE="${SDKMAN_DIR}/var/candidates"
SDKMAN_CANDIDATES_CSV=$(cat "$SDKMAN_CANDIDATES_CACHE")
__sdkman_echo_debug "Setting candidates csv: $SDKMAN_CANDIDATES_CSV"
if [[ "$zsh_shell" == 'true' ]]; then
SDKMAN_CANDIDATES=( ${(s:,:)SDKMAN_CANDIDATES_CSV} )
else

View File

@@ -53,7 +53,9 @@ function sdk {
#
# Various sanity checks and default settings
#
mkdir -p "$SDKMAN_DIR"
# Check candidates cache
___sdkman_check_candidates_cache "$SDKMAN_CANDIDATES_CACHE" || return 1
# Always presume internet availability
SDKMAN_AVAILABLE="true"

View File

@@ -2,6 +2,7 @@ Feature: Upgrade Candidate
Background:
Given the internet is reachable
And the candidates cache is initialised with "grails"
And an initialised environment
Scenario: Display upgradable candidate version in use when it is upgradable

View File

@@ -13,7 +13,7 @@ class BetaChannelBootstrapSpec extends SdkmanEnvSpecification {
def setup() {
versionCache = new File("${sdkmanDotDirectory}/var", "version")
sdkmanBashEnvBuilder.withCandidatesCache(["groovy"])
sdkmanBashEnvBuilder.withCandidates(["groovy"])
}
void "should attempt immediate upgrade of stable to beta version if beta channel is first enabled"() {

View File

@@ -1,176 +0,0 @@
package sdkman.specs
import sdkman.support.SdkmanEnvSpecification
import static java.lang.System.currentTimeMillis
class CandidatesCacheBootstrapSpec extends SdkmanEnvSpecification {
static final MORE_THAN_A_DAY_IN_MILLIS = 24 * 61 * 60 * 1000
static final LEGACY_API = "http://localhost:8080/1"
static final LEGACY_VERSIONS_STABLE_ENDPOINT = "$LEGACY_API/candidates/app/stable"
static final LEGACY_VERSIONS_BETA_ENDPOINT = "$LEGACY_API/candidates/app/beta"
static final CURRENT_API = "http://localhost:8080/2"
static final CURRENT_CANDIDATES_ENDPOINT = "$CURRENT_API/candidates/all"
File candidatesCache
def setup() {
candidatesCache = new File("${sdkmanDotDirectory}/var", "candidates")
curlStub.primeWith(LEGACY_VERSIONS_STABLE_ENDPOINT, "echo x.y.y")
.primeWith(LEGACY_VERSIONS_BETA_ENDPOINT, "echo x.y.z")
sdkmanBashEnvBuilder.withConfiguration("sdkman_debug_mode", "true")
}
void "should not query server if unexpired candidates cache is found"() {
given:
bash = sdkmanBashEnvBuilder
.withCandidatesCache(['gradle', 'sbt'])
.build()
and:
bash.start()
when:
bash.execute("source $bootstrapScript")
bash.execute('echo $SDKMAN_CANDIDATES_CSV')
then:
candidatesCache.exists()
candidatesCache.text.contains("gradle,sbt")
and:
bash.output.contains "gradle,sbt"
}
void "should fetch and store candidates in cache if cache is empty"() {
given:
curlStub.primeWith(CURRENT_CANDIDATES_ENDPOINT, "echo groovy,scala")
bash = sdkmanBashEnvBuilder
.withCandidatesCache([])
.withLegacyService(LEGACY_API)
.build()
and:
bash.start()
when:
bash.execute("source $bootstrapScript")
bash.execute('echo $SDKMAN_CANDIDATES_CSV')
then:
candidatesCache.exists()
candidatesCache.text.contains("groovy,scala")
and:
bash.output.contains("groovy,scala")
}
void "should fetch candidates and refresh cache if older than a day"() {
given:
curlStub.primeWith(CURRENT_CANDIDATES_ENDPOINT, "echo groovy,scala")
bash = sdkmanBashEnvBuilder
.withLegacyService(LEGACY_API)
.withCandidatesCache(['groovy'])
.build()
and:
candidatesCache.setLastModified(currentTimeMillis() - MORE_THAN_A_DAY_IN_MILLIS)
and:
bash.start()
when:
bash.execute("source $bootstrapScript")
bash.execute('echo $SDKMAN_CANDIDATES_CSV')
then:
candidatesCache.exists()
candidatesCache.text.contains('groovy,scala')
and:
bash.output.contains("groovy,scala")
}
void "should ignore candidates if api is offline"() {
given:
def candidates = ['groovy', 'scala']
curlStub.primeWith(CURRENT_CANDIDATES_ENDPOINT, "echo ''")
bash = sdkmanBashEnvBuilder
.withLegacyService(LEGACY_API)
.withCandidatesCache(candidates)
.build()
and:
candidatesCache.setLastModified(currentTimeMillis() - MORE_THAN_A_DAY_IN_MILLIS)
and:
bash.start()
when:
bash.execute("source $bootstrapScript")
bash.execute('echo $SDKMAN_CANDIDATES_CSV')
then:
candidatesCache.text.contains('groovy,scala')
and:
bash.output.contains("groovy,scala")
}
void "should ignore candidates if api returns garbage"() {
given:
def candidates = ['groovy', 'scala']
curlStub.primeWith(CURRENT_CANDIDATES_ENDPOINT, "echo '<html><title>sorry</title></html>'")
bash = sdkmanBashEnvBuilder
.withLegacyService(LEGACY_API)
.withCandidatesCache(candidates)
.build()
and:
candidatesCache.setLastModified(currentTimeMillis() - MORE_THAN_A_DAY_IN_MILLIS)
and:
bash.start()
when:
bash.execute("source $bootstrapScript")
bash.execute('echo $SDKMAN_CANDIDATES_CSV')
then:
candidatesCache.text.contains('groovy,scala')
and:
bash.output.contains("groovy,scala")
}
void "should query api if not subscribed to beta channel"() {
given:
curlStub.primeWith(CURRENT_CANDIDATES_ENDPOINT, "echo groovy,scala")
bash = sdkmanBashEnvBuilder
.withLegacyService(LEGACY_API)
.withCurrentService(CURRENT_API)
.withConfiguration("sdkman_beta_channel", "false")
.withCandidatesCache(['groovy'])
.build()
and:
candidatesCache.setLastModified(currentTimeMillis() - MORE_THAN_A_DAY_IN_MILLIS)
and:
bash.start()
when:
bash.execute("source $bootstrapScript")
bash.execute('echo $SDKMAN_CANDIDATES_CSV')
then:
candidatesCache.exists()
candidatesCache.text.contains('groovy,scala')
and:
bash.output.contains("groovy,scala")
}
}

View File

@@ -0,0 +1,91 @@
package sdkman.specs
import sdkman.support.SdkmanEnvSpecification
class CandidatesCacheUpdateSpec extends SdkmanEnvSpecification {
static final LEGACY_API = "http://localhost:8080/1"
static final LEGACY_VERSIONS_STABLE_ENDPOINT = "$LEGACY_API/candidates/app/stable"
static final LEGACY_VERSIONS_BETA_ENDPOINT = "$LEGACY_API/candidates/app/beta"
static final CURRENT_API = "http://localhost:8080/2"
static final BROADCAST_API_LATEST_ID_ENDPOINT = "$CURRENT_API/broadcast/latest/id"
File candidatesCache
def setup() {
candidatesCache = new File("${sdkmanDotDirectory}/var", "candidates")
curlStub.primeWith(LEGACY_VERSIONS_STABLE_ENDPOINT, "echo x.y.y")
.primeWith(LEGACY_VERSIONS_BETA_ENDPOINT, "echo x.y.z")
.primeWith(BROADCAST_API_LATEST_ID_ENDPOINT, "echo dbfb025be9f97fda2052b5febcca0155")
sdkmanBashEnvBuilder.withConfiguration("sdkman_debug_mode", "true")
}
void "should issue a warning if cache is empty"() {
given:
bash = sdkmanBashEnvBuilder
.withCandidates([])
.withLegacyService(LEGACY_API)
.build()
and:
bash.start()
when:
bash.execute("source $bootstrapScript")
bash.execute("sdk version")
then:
bash.output.contains('Warning! Cache is corrupt. SDKMAN can not be used until updated.')
bash.output.contains('$ sdk update')
and:
!bash.output.contains("SDKMAN 5.0.0")
}
void "should issue a warning if cache is older than a month"() {
given:
bash = sdkmanBashEnvBuilder
.withLegacyService(LEGACY_API)
.withCandidates(['groovy'])
.build()
and:
candidatesCache.setLastModified(((new Date() - 31) as Date).time)
and:
bash.start()
when:
bash.execute("source $bootstrapScript")
bash.execute("sdk version")
then:
bash.output.contains('Warning! SDKMAN out-of-date and requires an update.')
bash.output.contains('$ sdk update')
and:
bash.output.contains('SDKMAN 5.0.0')
}
void "should log a success message in debug mode when no update needed"() {
given:
bash = sdkmanBashEnvBuilder
.withLegacyService(LEGACY_API)
.withCandidates(['groovy'])
.build()
and:
bash.start()
when:
bash.execute("source $bootstrapScript")
bash.execute("sdk version")
then:
bash.output.contains('No update needed. Using existing candidates cache')
and:
bash.output.contains('SDKMAN 5.0.0')
}
}

View File

@@ -8,6 +8,13 @@ import static java.nio.file.Files.createSymbolicLink
class CurrentCommandSpec extends SdkmanEnvSpecification {
static final CURRENT_API = "http://localhost:8080/2"
static final BROADCAST_API_LATEST_ID_ENDPOINT = "$CURRENT_API/broadcast/latest/id"
def setup() {
curlStub.primeWith(BROADCAST_API_LATEST_ID_ENDPOINT, "echo dbfb025be9f97fda2052b5febcca0155")
}
void "should display current version of all candidates installed"() {
given:
def installedCandidates = [
@@ -34,7 +41,7 @@ class CurrentCommandSpec extends SdkmanEnvSpecification {
bash = sdkmanBashEnvBuilder
.withOfflineMode(false)
.withCandidatesCache(allCandidates)
.withVersionCache("5.0.0")
.withCandidates(installedCandidates.keySet().toList())
.build()

View File

@@ -12,7 +12,6 @@ class InitialisationSpec extends SdkmanEnvSpecification {
def setup() {
bash = sdkmanBashEnvBuilder
.withCandidatesCache(allCandidates)
.withCandidates(allCandidates)
.withVersionCache("x.y.z")
.build()

View File

@@ -11,7 +11,6 @@ class SdkCompatibilitySpec extends SdkmanEnvSpecification {
def setup() {
bash = sdkmanBashEnvBuilder
.withCandidatesCache(allCandidates)
.withCandidates(allCandidates)
.withVersionCache("x.y.z")
.build()

View File

@@ -44,6 +44,8 @@ candidatesFile = new File(varDir, "candidates")
versionFile = new File(varDir, "version")
initScript = new File(binDir, "sdkman-init.sh")
localCandidates = ['groovy', 'grails', 'java', 'kotlin', 'scala']
bash = null
if(!binding.hasVariable("wireMock")) {

View File

@@ -94,6 +94,7 @@ And(~'^an initialised environment$') {->
.withJdkHome(javaHome)
.withHttpProxy(HTTP_PROXY)
.withVersionCache(sdkmanVersion)
.withCandidates(localCandidates)
.withSdkmanVersion(sdkmanVersion)
.build()
}
@@ -133,4 +134,8 @@ And(~'^the system is bootstrapped again$') {->
And(~/^the sdkman version is "([^"]*)"$/) { String version ->
sdkmanVersion = version
}
And(~/^the candidates cache is initialised with "(.*)"$/) { String candidate ->
localCandidates << candidate
}

View File

@@ -1,5 +1,6 @@
package sdkman.steps
import cucumber.api.DataTable
import sdkman.support.UnixUtils
import static cucumber.api.groovy.EN.And
@@ -100,3 +101,7 @@ And(~/^a download request was made for "(.*)" "(.*)" on "(.*)" with cookie "(.*)
And(~/^a cookie is required for installing "(.*)" "(.*)" on "(.*)"$/) { String candidate, String version, String platform ->
//handled by the hook in subsequent step
}
And(~/^the following candidates are currently available from remote API:$/) { DataTable dt ->
primeEndpointWithString("/candidates/all", dt.asList(String).drop(1).join(","))
}

View File

@@ -0,0 +1,13 @@
package sdkman.steps
import cucumber.api.DataTable
import static cucumber.api.groovy.EN.*
And(~/^the following candidates are available for installation in local cache:$/) { DataTable dt ->
localCandidates = dt.asList(String).drop(1)
}
And(~/^the Candidates cache should contain "(.*)"$/) { String candidates ->
assert candidatesFile.text.trim() == candidates
}

View File

@@ -1,7 +1,5 @@
package sdkman.stubs
import sdkman.support.UnixUtils
import static com.github.tomakehurst.wiremock.client.WireMock.*
class WebServiceStub {