@ -3,7 +3,6 @@ import * as main from '../main';
import * as reporter from '../reporter' ;
import { getDockerfilePath } from '../context' ;
import * as setupBuilder from '../setup_builder' ;
import { Metric_MetricType } from '@buf/blacksmith_vm-agent.bufbuild_es/stickydisk/v1/stickydisk_pb' ;
jest . mock ( '@actions/core' , ( ) = > ( {
debug : jest.fn ( ) ,
@ -25,21 +24,15 @@ jest.mock('../reporter', () => {
const actual = jest . requireActual ( '../reporter' ) ;
return {
. . . actual ,
reportBuildPushActionFailure : jest.fn ( ) . mockResolvedValue ( undefined ) ,
reportMetric : jest.fn ( ) . mockImplementation ( ( type : Metric_MetricType ) = > Promise . resolve ( ) )
reportBuildPushActionFailure : jest.fn ( ) . mockResolvedValue ( undefined )
} ;
} ) ;
jest . mock ( '../setup_builder' , ( ) = > ( {
. . . jest . requireActual ( '../setup_builder' ) ,
startAndConfigureBuildkitd : jest.fn ( ) ,
setupStickyDisk : jest.fn ( ) ,
getNumCPUs : jest.fn ( ) . mockResolvedValue ( 4 ) ,
leaveTailnet : jest.fn ( ) . mockResolvedValue ( undefined ) ,
getTailscaleIP : jest.fn ( )
reportBuildStart : jest.fn ( )
} ) ) ;
describe ( ' startBlacksmithBuilder ', ( ) = > {
describe ( 'reportBuildMetrics' , ( ) = > {
let mockInputs ;
beforeEach ( ( ) = > {
@ -51,110 +44,47 @@ describe('startBlacksmithBuilder', () => {
} ;
} ) ;
test ( 'should handle missing dockerfile path with nofallback=false ', async ( ) = > {
test ( 'should handle missing dockerfile path ', async ( ) = > {
( getDockerfilePath as jest . Mock ) . mockReturnValue ( null ) ;
const result = await main . startBlacksmithBuilder ( mockInputs ) ;
const result = await main . reportBuildMetrics ( mockInputs ) ;
expect ( result ) . to Equal( { addr : null , buildId : null , exposeId : '' } ) ;
expect ( core . warning ) . toHaveBeenCalledWith ( 'Error during Blacksmith builder setup: Failed to resolve dockerfile path. Falling back to a local build. ') ;
expect ( reporter . reportBuildPushActionFailure ) . toHaveBeenCalledWith ( new Error ( 'Failed to resolve dockerfile path' ) , ' starting blacksmith builder ') ;
expect ( result ) . to BeNull( ) ;
expect ( core . warning ) . toHaveBeenCalledWith ( 'Error during build metrics reporting: Failed to resolve dockerfile path ') ;
expect ( reporter . reportBuildPushActionFailure ) . toHaveBeenCalledWith ( new Error ( 'Failed to resolve dockerfile path' ) , ' reporting build metrics ') ;
} ) ;
test ( 'should handle missing dockerfile path with nofallback=true' , async ( ) = > {
( getDockerfilePath as jest . Mock ) . mockReturnValue ( null ) ;
mockInputs . nofallback = true ;
await expect ( main . startBlacksmithBuilder ( mockInputs ) ) . rejects . toThrow ( 'Failed to resolve dockerfile path' ) ;
expect ( core . warning ) . toHaveBeenCalledWith ( 'Error during Blacksmith builder setup: Failed to resolve dockerfile path. Failing the build because nofallback is set.' ) ;
expect ( reporter . reportBuildPushActionFailure ) . toHaveBeenCalledWith ( new Error ( 'Failed to resolve dockerfile path' ) , 'starting blacksmith builder' ) ;
} ) ;
test ( 'should handle error in setupStickyDisk with nofallback=false' , async ( ) = > {
test ( 'should successfully report build start' , async ( ) = > {
const mockBuildId = 'test-build-id' ;
( getDockerfilePath as jest . Mock ) . mockReturnValue ( '/path/to/Dockerfile' ) ;
( setupBuilder . setupStickyDisk as jest . Mock ) . mockRejectedValue ( new Error ( 'Failed to obtain Blacksmith builder' ) ) ;
( setupBuilder . reportBuildStart as jest . Mock ) . mockResolvedValue ( { docker_build_id : mockBuildId } ) ;
mockInputs . nofallback = false ;
const result = await main . startBlacksmithBuilder ( mockInputs ) ;
const result = await main . reportBuildMetrics ( mockInputs ) ;
expect ( result ) . to Equal( { addr : null , buildId : null , exposeId : '' } ) ;
expect ( core. warning ) . toHaveBeenCalledWith ( 'Error during Blacksmith builder setup: Failed to obtain Blacksmith builder. Falling back to a local build. ') ;
expect ( reporter . reportBuildPushActionFailure ) . toHaveBeenCalledWith ( new Error ( 'Failed to obtain Blacksmith builder' ) , 'starting blacksmith builder' ) ;
expect ( result ) . toBe ( mockBuildId ) ;
expect ( setupBuilder . reportBuildStart ) . toHaveBeenCalledWith ( '/path/to/Dockerfile' ) ;
expect ( reporter . reportBuildPushActionFailure ) . not . toHaveBeenCalled ( ) ;
} ) ;
test ( 'should handle error in setupStickyDisk with nofallback=true ', async ( ) = > {
test ( 'should handle reportBuildStart returning null ', async ( ) = > {
( getDockerfilePath as jest . Mock ) . mockReturnValue ( '/path/to/Dockerfile' ) ;
const error = new Error ( 'Failed to obtain Blacksmith builder' ) ;
( setupBuilder . setupStickyDisk as jest . Mock ) . mockRejectedValue ( error ) ;
mockInputs . nofallback = true ;
( setupBuilder . reportBuildStart as jest . Mock ) . mockResolvedValue ( null ) ;
await expect ( main . startBlacksmithBuilder ( mockInputs ) ) . rejects . toThrow ( error ) ;
expect ( core . warning ) . toHaveBeenCalledWith ( 'Error during Blacksmith builder setup: Failed to obtain Blacksmith builder. Failing the build because nofallback is set.' ) ;
expect ( reporter . reportBuildPushActionFailure ) . toHaveBeenCalledWith ( error , 'starting blacksmith builder' ) ;
} ) ;
const result = await main . reportBuildMetrics ( mockInputs ) ;
test ( 'should successfully start buildkitd when setup succeeds' , async ( ) = > {
const mockBuildkitdAddr = 'unix:///run/buildkit/buildkitd.sock' ;
const mockExposeId = 'test-expose-id' ;
const mockBuildId = 'test-build-id' ;
const mockDevice = '/dev/vdb' ;
const mockParallelism = 4 ;
( getDockerfilePath as jest . Mock ) . mockReturnValue ( '/path/to/Dockerfile' ) ;
( setupBuilder . setupStickyDisk as jest . Mock ) . mockResolvedValue ( {
device : mockDevice ,
buildId : mockBuildId ,
exposeId : mockExposeId
} ) ;
( setupBuilder . getNumCPUs as jest . Mock ) . mockResolvedValue ( mockParallelism ) ;
( setupBuilder . startAndConfigureBuildkitd as jest . Mock ) . mockResolvedValue ( mockBuildkitdAddr ) ;
const result = await main . startBlacksmithBuilder ( mockInputs ) ;
expect ( result ) . toEqual ( {
addr : mockBuildkitdAddr ,
buildId : mockBuildId ,
exposeId : mockExposeId
} ) ;
expect ( setupBuilder . startAndConfigureBuildkitd ) . toHaveBeenCalledWith ( mockParallelism , false , [ ] ) ;
expect ( result ) . toBeNull ( ) ;
expect ( setupBuilder . reportBuildStart ) . toHaveBeenCalledWith ( '/path/to/Dockerfile' ) ;
expect ( reporter . reportBuildPushActionFailure ) . not . toHaveBeenCalled ( ) ;
} ) ;
test ( 'should handle buildkitd startup failure with nofallback=false' , async ( ) = > {
const mockDevice = '/dev/vdb' ;
const mockParallelism = 4 ;
test ( 'should handle error in reportBuildStart' , async ( ) = > {
( getDockerfilePath as jest . Mock ) . mockReturnValue ( '/path/to/Dockerfile' ) ;
( setupBuilder . setupStickyDisk as jest . Mock ) . mockResolvedValue ( {
device : mockDevice ,
buildId : 'test-build-id' ,
exposeId : 'test-expose-id'
} ) ;
( setupBuilder . getNumCPUs as jest . Mock ) . mockResolvedValue ( mockParallelism ) ;
( setupBuilder . startAndConfigureBuildkitd as jest . Mock ) . mockRejectedValue ( new Error ( 'Failed to start buildkitd' ) ) ;
mockInputs . nofallback = false ;
const result = await main . startBlacksmithBuilder ( mockInputs ) ;
expect ( result ) . toEqual ( { addr : null , buildId : null , exposeId : '' } ) ;
expect ( core . warning ) . toHaveBeenCalledWith ( 'Error during buildkitd setup: Failed to start buildkitd. Falling back to a local build.' ) ;
expect ( reporter . reportBuildPushActionFailure ) . toHaveBeenCalled ( ) ;
} ) ;
( setupBuilder . reportBuildStart as jest . Mock ) . mockRejectedValue ( new Error ( 'API error' ) ) ;
test ( 'should throw error when buildkitd fails and nofallback is true' , async ( ) = > {
const mockDevice = '/dev/vdb' ;
const mockParallelism = 4 ;
( getDockerfilePath as jest . Mock ) . mockReturnValue ( '/path/to/Dockerfile' ) ;
( setupBuilder . setupStickyDisk as jest . Mock ) . mockResolvedValue ( {
device : mockDevice ,
buildId : 'test-build-id' ,
exposeId : 'test-expose-id'
} ) ;
( setupBuilder . getNumCPUs as jest . Mock ) . mockResolvedValue ( mockParallelism ) ;
( setupBuilder . startAndConfigureBuildkitd as jest . Mock ) . mockRejectedValue ( new Error ( 'Failed to start buildkitd' ) ) ;
mockInputs . nofallback = true ;
await expect ( main . startBlacksmithBuilder ( mockInputs ) ) . rejects . toThrow ( 'Failed to start buildkitd' ) ;
expect ( core . warning ) . toHaveBeenCalledWith ( 'Error during buildkitd setup: Failed to start buildkitd. Failing the build because nofallback is set.' ) ;
expect ( reporter . reportBuildPushActionFailure ) . toHaveBeenCalled ( ) ;
const result = await main . reportBuildMetrics ( mockInputs ) ;
expect ( result ) . toBeNull ( ) ;
expect ( core . warning ) . toHaveBeenCalledWith ( 'Error during build metrics reporting: API error' ) ;
expect ( reporter . reportBuildPushActionFailure ) . toHaveBeenCalledWith ( new Error ( 'API error' ) , 'reporting build metrics' ) ;
} ) ;
} ) ;