2015-05-27 19:23:49 +00:00
package notifications
import (
"testing"
2020-08-24 11:18:39 +00:00
"github.com/distribution/distribution/v3"
2023-05-09 11:18:47 +00:00
"github.com/distribution/distribution/v3/manifest/schema1" //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
2020-08-24 11:18:39 +00:00
"github.com/distribution/distribution/v3/reference"
v2 "github.com/distribution/distribution/v3/registry/api/v2"
"github.com/distribution/distribution/v3/uuid"
2018-03-14 00:08:11 +00:00
events "github.com/docker/go-events"
2016-01-20 19:21:04 +00:00
"github.com/docker/libtrust"
2016-12-17 00:28:34 +00:00
"github.com/opencontainers/go-digest"
2015-05-27 19:23:49 +00:00
)
var (
// common environment for expected manifest events.
repo = "test/repo"
source = SourceRecord {
Addr : "remote.test" ,
InstanceID : uuid . Generate ( ) . String ( ) ,
}
2016-02-23 01:49:23 +00:00
ub = mustUB ( v2 . NewURLBuilderFromString ( "http://test.example.com/" , false ) )
2015-05-27 19:23:49 +00:00
actor = ActorRecord {
Name : "test" ,
}
request = RequestRecord { }
2023-05-09 11:18:47 +00:00
layers = [ ] schema1 . FSLayer { //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
2018-06-27 15:47:40 +00:00
{
BlobSum : "asdf" ,
} ,
{
BlobSum : "qwer" ,
} ,
}
2023-05-09 11:18:47 +00:00
m = schema1 . Manifest { //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
2018-06-27 15:47:40 +00:00
Name : repo ,
Tag : "latest" ,
FSLayers : layers ,
2015-05-27 19:23:49 +00:00
}
2023-05-09 11:18:47 +00:00
sm * schema1 . SignedManifest //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
2015-05-27 19:23:49 +00:00
payload [ ] byte
dgst digest . Digest
)
func TestEventBridgeManifestPulled ( t * testing . T ) {
2018-03-14 00:08:11 +00:00
l := createTestEnv ( t , testSinkFn ( func ( event events . Event ) error {
checkCommonManifest ( t , EventActionPull , event )
2015-05-27 19:23:49 +00:00
return nil
} ) )
2017-01-14 01:06:03 +00:00
repoRef , _ := reference . WithName ( repo )
2015-12-15 22:35:23 +00:00
if err := l . ManifestPulled ( repoRef , sm ) ; err != nil {
2015-05-27 19:23:49 +00:00
t . Fatalf ( "unexpected error notifying manifest pull: %v" , err )
}
}
func TestEventBridgeManifestPushed ( t * testing . T ) {
2018-03-14 00:08:11 +00:00
l := createTestEnv ( t , testSinkFn ( func ( event events . Event ) error {
checkCommonManifest ( t , EventActionPush , event )
2015-05-27 19:23:49 +00:00
return nil
} ) )
2017-01-14 01:06:03 +00:00
repoRef , _ := reference . WithName ( repo )
2015-12-15 22:35:23 +00:00
if err := l . ManifestPushed ( repoRef , sm ) ; err != nil {
2015-05-27 19:23:49 +00:00
t . Fatalf ( "unexpected error notifying manifest pull: %v" , err )
}
}
2016-03-18 22:30:47 +00:00
func TestEventBridgeManifestPushedWithTag ( t * testing . T ) {
2018-03-14 00:08:11 +00:00
l := createTestEnv ( t , testSinkFn ( func ( event events . Event ) error {
checkCommonManifest ( t , EventActionPush , event )
if event . ( Event ) . Target . Tag != "latest" {
t . Fatalf ( "missing or unexpected tag: %#v" , event . ( Event ) . Target )
2016-03-18 22:30:47 +00:00
}
return nil
} ) )
2017-01-14 01:06:03 +00:00
repoRef , _ := reference . WithName ( repo )
2016-03-18 22:30:47 +00:00
if err := l . ManifestPushed ( repoRef , sm , distribution . WithTag ( m . Tag ) ) ; err != nil {
t . Fatalf ( "unexpected error notifying manifest pull: %v" , err )
}
}
func TestEventBridgeManifestPulledWithTag ( t * testing . T ) {
2018-03-14 00:08:11 +00:00
l := createTestEnv ( t , testSinkFn ( func ( event events . Event ) error {
checkCommonManifest ( t , EventActionPull , event )
if event . ( Event ) . Target . Tag != "latest" {
t . Fatalf ( "missing or unexpected tag: %#v" , event . ( Event ) . Target )
2016-03-18 22:30:47 +00:00
}
return nil
} ) )
2017-01-14 01:06:03 +00:00
repoRef , _ := reference . WithName ( repo )
2016-03-18 22:30:47 +00:00
if err := l . ManifestPulled ( repoRef , sm , distribution . WithTag ( m . Tag ) ) ; err != nil {
t . Fatalf ( "unexpected error notifying manifest pull: %v" , err )
}
}
2015-05-27 19:23:49 +00:00
func TestEventBridgeManifestDeleted ( t * testing . T ) {
2018-03-14 00:08:11 +00:00
l := createTestEnv ( t , testSinkFn ( func ( event events . Event ) error {
checkDeleted ( t , EventActionDelete , event )
if event . ( Event ) . Target . Digest != dgst {
t . Fatalf ( "unexpected digest on event target: %q != %q" , event . ( Event ) . Target . Digest , dgst )
2018-07-18 18:25:59 +00:00
}
2015-05-27 19:23:49 +00:00
return nil
} ) )
2017-01-14 01:06:03 +00:00
repoRef , _ := reference . WithName ( repo )
2016-01-28 17:56:37 +00:00
if err := l . ManifestDeleted ( repoRef , dgst ) ; err != nil {
2015-05-27 19:23:49 +00:00
t . Fatalf ( "unexpected error notifying manifest pull: %v" , err )
}
}
2018-07-18 18:25:59 +00:00
func TestEventBridgeTagDeleted ( t * testing . T ) {
2018-03-14 00:08:11 +00:00
l := createTestEnv ( t , testSinkFn ( func ( event events . Event ) error {
checkDeleted ( t , EventActionDelete , event )
if event . ( Event ) . Target . Tag != m . Tag {
t . Fatalf ( "unexpected tag on event target: %q != %q" , event . ( Event ) . Target . Tag , m . Tag )
2018-07-18 18:25:59 +00:00
}
return nil
} ) )
repoRef , _ := reference . WithName ( repo )
if err := l . TagDeleted ( repoRef , m . Tag ) ; err != nil {
t . Fatalf ( "unexpected error notifying tag deletion: %v" , err )
}
}
2018-08-03 05:58:52 +00:00
func TestEventBridgeRepoDeleted ( t * testing . T ) {
2018-03-14 00:08:11 +00:00
l := createTestEnv ( t , testSinkFn ( func ( event events . Event ) error {
checkDeleted ( t , EventActionDelete , event )
2018-08-03 05:58:52 +00:00
return nil
} ) )
repoRef , _ := reference . WithName ( repo )
if err := l . RepoDeleted ( repoRef ) ; err != nil {
t . Fatalf ( "unexpected error notifying repo deletion: %v" , err )
}
}
2015-05-27 19:23:49 +00:00
func createTestEnv ( t * testing . T , fn testSinkFn ) Listener {
pk , err := libtrust . GenerateECP256PrivateKey ( )
if err != nil {
t . Fatalf ( "error generating private key: %v" , err )
}
2023-05-09 11:18:47 +00:00
sm , err = schema1 . Sign ( & m , pk ) //nolint:staticcheck // Ignore SA1019: "github.com/distribution/distribution/v3/manifest/schema1" is deprecated, as it's used for backward compatibility.
2015-05-27 19:23:49 +00:00
if err != nil {
t . Fatalf ( "error signing manifest: %v" , err )
}
2016-01-20 19:21:04 +00:00
payload = sm . Canonical
2015-12-14 22:30:51 +00:00
dgst = digest . FromBytes ( payload )
2015-05-27 19:23:49 +00:00
2018-06-27 15:47:40 +00:00
return NewBridge ( ub , source , actor , request , fn , true )
2015-05-27 19:23:49 +00:00
}
2018-03-14 00:08:11 +00:00
func checkDeleted ( t * testing . T , action string , event events . Event ) {
if event . ( Event ) . Source != source {
t . Fatalf ( "source not equal: %#v != %#v" , event . ( Event ) . Source , source )
2016-01-28 17:56:37 +00:00
}
2018-03-14 00:08:11 +00:00
if event . ( Event ) . Request != request {
t . Fatalf ( "request not equal: %#v != %#v" , event . ( Event ) . Request , request )
2016-01-28 17:56:37 +00:00
}
2018-03-14 00:08:11 +00:00
if event . ( Event ) . Actor != actor {
t . Fatalf ( "request not equal: %#v != %#v" , event . ( Event ) . Actor , actor )
2016-01-28 17:56:37 +00:00
}
2018-03-14 00:08:11 +00:00
if event . ( Event ) . Target . Repository != repo {
t . Fatalf ( "unexpected repository: %q != %q" , event . ( Event ) . Target . Repository , repo )
2016-01-28 17:56:37 +00:00
}
}
2018-03-14 00:08:11 +00:00
func checkCommonManifest ( t * testing . T , action string , event events . Event ) {
checkCommon ( t , event )
2015-05-27 19:23:49 +00:00
2018-03-14 00:08:11 +00:00
if event . ( Event ) . Action != action {
t . Fatalf ( "unexpected event action: %q != %q" , event . ( Event ) . Action , action )
2015-05-27 19:23:49 +00:00
}
2017-01-14 01:06:03 +00:00
repoRef , _ := reference . WithName ( repo )
2015-12-16 00:43:13 +00:00
ref , _ := reference . WithDigest ( repoRef , dgst )
u , err := ub . BuildManifestURL ( ref )
2015-05-27 19:23:49 +00:00
if err != nil {
t . Fatalf ( "error building expected url: %v" , err )
}
2018-03-14 00:08:11 +00:00
if event . ( Event ) . Target . URL != u {
t . Fatalf ( "incorrect url passed: \n%q != \n%q" , event . ( Event ) . Target . URL , u )
2015-05-27 19:23:49 +00:00
}
2018-06-27 15:47:40 +00:00
2018-03-14 00:08:11 +00:00
if len ( event . ( Event ) . Target . References ) != len ( layers ) {
t . Fatalf ( "unexpected number of references %v != %v" , len ( event . ( Event ) . Target . References ) , len ( layers ) )
2018-06-27 15:47:40 +00:00
}
2018-03-14 00:08:11 +00:00
for i , targetReference := range event . ( Event ) . Target . References {
2018-08-20 17:01:40 +00:00
if targetReference . Digest != layers [ i ] . BlobSum {
t . Fatalf ( "unexpected reference: %q != %q" , targetReference . Digest , layers [ i ] . BlobSum )
2018-06-27 15:47:40 +00:00
}
}
2015-05-27 19:23:49 +00:00
}
2018-03-14 00:08:11 +00:00
func checkCommon ( t * testing . T , event events . Event ) {
if event . ( Event ) . Source != source {
t . Fatalf ( "source not equal: %#v != %#v" , event . ( Event ) . Source , source )
2015-05-27 19:23:49 +00:00
}
2018-03-14 00:08:11 +00:00
if event . ( Event ) . Request != request {
t . Fatalf ( "request not equal: %#v != %#v" , event . ( Event ) . Request , request )
2015-05-27 19:23:49 +00:00
}
2018-03-14 00:08:11 +00:00
if event . ( Event ) . Actor != actor {
t . Fatalf ( "request not equal: %#v != %#v" , event . ( Event ) . Actor , actor )
2015-05-27 19:23:49 +00:00
}
2018-03-14 00:08:11 +00:00
if event . ( Event ) . Target . Digest != dgst {
t . Fatalf ( "unexpected digest on event target: %q != %q" , event . ( Event ) . Target . Digest , dgst )
2015-05-27 19:23:49 +00:00
}
2018-03-14 00:08:11 +00:00
if event . ( Event ) . Target . Length != int64 ( len ( payload ) ) {
t . Fatalf ( "unexpected target length: %v != %v" , event . ( Event ) . Target . Length , len ( payload ) )
2015-05-27 19:23:49 +00:00
}
2018-03-14 00:08:11 +00:00
if event . ( Event ) . Target . Repository != repo {
t . Fatalf ( "unexpected repository: %q != %q" , event . ( Event ) . Target . Repository , repo )
2015-05-27 19:23:49 +00:00
}
}
2018-03-14 00:08:11 +00:00
type testSinkFn func ( event events . Event ) error
2015-05-27 19:23:49 +00:00
2018-03-14 00:08:11 +00:00
func ( tsf testSinkFn ) Write ( event events . Event ) error {
return tsf ( event )
2015-05-27 19:23:49 +00:00
}
func ( tsf testSinkFn ) Close ( ) error { return nil }
func mustUB ( ub * v2 . URLBuilder , err error ) * v2 . URLBuilder {
if err != nil {
panic ( err )
}
return ub
}