Skip to content

Commit

Permalink
refactored and added tests
Browse files Browse the repository at this point in the history
Signed-off-by: munishchouhan <[email protected]>
  • Loading branch information
munishchouhan committed Dec 11, 2024
1 parent eef1629 commit d0237cb
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -152,27 +152,18 @@ class BuildLogServiceImpl implements BuildLogService {
if( !logs ) return
try {
String condaLock = extractCondaLockFile(logs)
if ( condaLock ){
log.debug "Storing conda lock for buildId: $buildId"

/* When a container image is cached, dockerfile does not get executed.
/* When a container image is cached, dockerfile does not get executed.
In that case condalock file will contain "cat environment.lock" because its not been executed.
So wave will check the previous builds of that container image
and render the condalock file from latest successful build
and replace with the current build's condalock file.
*/
if( condaLock.contains('cat environment.lock') ){
log.info "Container Image is already cached, uploading previously successful build's condalock file for buildId: $buildId"
def builds = persistenceService.allBuilds(buildId.split('-')[1].split('_')[0])
for (def build : builds) {
if ( build.succeeded() ){
def curCondaLock = fetchCondaLockString(build.buildId)
if( curCondaLock && !curCondaLock.contains('cat environment.lock') ){
condaLock = curCondaLock
}
}
}
}
if( condaLock && condaLock.contains('cat environment.lock') ){
condaLock = fetchValidCondaLock(buildId)
}

if ( condaLock ){
log.debug "Storing conda lock for buildId: $buildId"
final uploadRequest = UploadRequest.fromBytes(condaLock.bytes, condaLockKey(buildId))
objectStorageOperations.upload(uploadRequest)
}
Expand Down Expand Up @@ -217,4 +208,18 @@ class BuildLogServiceImpl implements BuildLogService {
.replaceAll(/#\d+ \d+\.\d+\s*/, '')
}

String fetchValidCondaLock(String buildId) {
log.info "Container Image is already cached, uploading previously successful build's condalock file for buildId: $buildId"
def builds = persistenceService.allBuilds(buildId.split('-')[1].split('_')[0])
for (def build : builds) {
if ( build.succeeded() ){
def curCondaLock = fetchCondaLockString(build.buildId)
if( curCondaLock && !curCondaLock.contains('cat environment.lock') ){
return curCondaLock
}
}
}
return null
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,19 @@ import spock.lang.Specification
import spock.lang.Unroll

import io.micronaut.objectstorage.InputStreamMapper
import io.micronaut.objectstorage.ObjectStorageOperations
import io.micronaut.objectstorage.aws.AwsS3Configuration
import io.micronaut.objectstorage.aws.AwsS3ObjectStorageEntry
import io.micronaut.objectstorage.aws.AwsS3Operations
import io.seqera.wave.service.persistence.PersistenceService
import io.seqera.wave.service.persistence.WaveBuildRecord
import io.seqera.wave.test.AwsS3TestContainer
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider
import software.amazon.awssdk.core.ResponseInputStream
import software.amazon.awssdk.regions.Region
import software.amazon.awssdk.services.s3.S3Client
import software.amazon.awssdk.services.s3.model.GetObjectResponse

/**
*
Expand Down Expand Up @@ -167,4 +173,74 @@ class BuildLogsServiceTest extends Specification implements AwsS3TestContainer {
noExceptionThrown()
}

def 'should return valid conda lock from previous successful build'() {
given:
def persistenceService = Mock(PersistenceService)
def objectStorageOperations = Mock(ObjectStorageOperations)
def service = new BuildLogServiceImpl(persistenceService: persistenceService, objectStorageOperations: objectStorageOperations)
def build1 = Mock(WaveBuildRecord) {
succeeded() >> false
buildId >> 'bd-abc_1'
}
def build2 = Mock(WaveBuildRecord) {
succeeded() >> true
buildId >> 'bd-abc_2'
}
def build3 = Mock(WaveBuildRecord) {
succeeded() >> true
buildId >> 'bd-abc_3'
}
def responseMetadata = GetObjectResponse.builder()
.contentLength(1024L)
.contentType("text/plain")
.build()
def contentStream = new ByteArrayInputStream("valid conda lock".bytes);
def responseInputStream = new ResponseInputStream<>(responseMetadata, contentStream);
persistenceService.allBuilds(_) >> [build1, build2]
objectStorageOperations.retrieve(service.condaLockKey('bd-abc_2')) >> Optional.of(new AwsS3ObjectStorageEntry('bd-abc_2', responseInputStream))

expect:
service.fetchValidCondaLock('bd-abc_3') == 'valid conda lock'
}

def 'should return null when no successful build has valid conda lock'() {
given:
def persistenceService = Mock(PersistenceService)
def objectStorageOperations = Mock(ObjectStorageOperations)
def service = new BuildLogServiceImpl(persistenceService: persistenceService, objectStorageOperations: objectStorageOperations)
def build1 = Mock(WaveBuildRecord) {
succeeded() >> false
buildId >> 'bd-abc_1'
}
def build2 = Mock(WaveBuildRecord) {
succeeded() >> true
buildId >> 'bd-abc_2'
}
def build3 = Mock(WaveBuildRecord) {
succeeded() >> true
buildId >> 'bd-abc_3'
}
def responseMetadata = GetObjectResponse.builder()
.contentLength(1024L)
.contentType("text/plain")
.build()
def contentStream = new ByteArrayInputStream("cat environment.lock".bytes);
def responseInputStream = new ResponseInputStream<>(responseMetadata, contentStream);
persistenceService.allBuilds(_) >> [build1, build2]
objectStorageOperations.retrieve(service.condaLockKey('bd-abc_2')) >> Optional.of(new AwsS3ObjectStorageEntry('bd-abc_2', responseInputStream))

expect:
service.fetchValidCondaLock('bd-abc_3') == null
}

def 'should return null when no builds are available'() {
given:
def persistenceService = Mock(PersistenceService)
def service = new BuildLogServiceImpl(persistenceService: persistenceService)
persistenceService.allBuilds(_) >> []

expect:
service.fetchValidCondaLock('bd-abc_1') == null
}

}

0 comments on commit d0237cb

Please sign in to comment.