@@ -745,3 +745,122 @@ plugs:
745745 err := pack .CheckSkeleton (& buf , sourceDir )
746746 c .Assert (err , ErrorMatches , `content interface plug "plug-missing" target "\$SNAP/missing" does not exist` )
747747}
748+
749+ type layoutSourceTestCase struct {
750+ summary string
751+ base string
752+ layout string // layout fragment (indented, under "layout:" key)
753+ plugs string // plugs fragment (indented, under "plugs:" key, optional)
754+ files []string // paths to create: trailing "/" = dir, otherwise file
755+ errMatch string // expected error regex, "" = no error expected
756+ }
757+
758+ func (s * packSuite ) checkSkeletonLayoutSource (c * C , tc layoutSourceTestCase ) {
759+ yamlStr := fmt .Sprintf ("name: hello\n version: 0\n base: %s\n " , tc .base )
760+ if tc .plugs != "" {
761+ yamlStr += "plugs:\n " + tc .plugs
762+ }
763+ yamlStr += "layout:\n " + tc .layout
764+
765+ sourceDir := makeExampleSnapSourceDir (c , yamlStr )
766+ for _ , f := range tc .files {
767+ path := filepath .Join (sourceDir , f )
768+ if strings .HasSuffix (f , "/" ) {
769+ c .Assert (os .MkdirAll (path , 0755 ), IsNil )
770+ } else {
771+ c .Assert (os .MkdirAll (filepath .Dir (path ), 0755 ), IsNil )
772+ c .Assert (os .WriteFile (path , []byte ("" ), 0644 ), IsNil )
773+ }
774+ }
775+ var buf bytes.Buffer
776+ err := pack .CheckSkeleton (& buf , sourceDir )
777+ if tc .errMatch == "" {
778+ c .Assert (err , IsNil , Commentf ("test: %s" , tc .summary ))
779+ } else {
780+ c .Assert (err , ErrorMatches , tc .errMatch , Commentf ("test: %s" , tc .summary ))
781+ }
782+ }
783+
784+ func (s * packSuite ) TestCheckSkeletonLayoutSourceValid (c * C ) {
785+ for _ , tc := range []layoutSourceTestCase {
786+ {
787+ summary : "bind source directory exists" ,
788+ base : "core26" ,
789+ layout : " /opt/lib:\n bind: $SNAP/lib\n " ,
790+ files : []string {"lib/" },
791+ },
792+ {
793+ summary : "bind-file source file exists" ,
794+ base : "core26" ,
795+ layout : " /opt/foo.conf:\n bind-file: $SNAP/foo.conf\n " ,
796+ files : []string {"foo.conf" },
797+ },
798+ {
799+ summary : "source under content target with full path present" ,
800+ base : "core26" ,
801+ plugs : " gnome:\n interface: content\n target: $SNAP/gnome-platform\n " ,
802+ layout : " /usr/lib/webkit:\n bind: $SNAP/gnome-platform/usr/lib/webkit\n " ,
803+ files : []string {"gnome-platform/usr/lib/webkit/" },
804+ },
805+ {
806+ summary : "source is content target directory" ,
807+ base : "core26" ,
808+ layout : " /opt/gnome:\n bind: $SNAP/gnome-platform\n " ,
809+ files : []string {"gnome-platform/" },
810+ },
811+ {
812+ summary : "symlink layout not checked" ,
813+ base : "core26" ,
814+ layout : " /opt/data:\n symlink: $SNAP/data\n " ,
815+ },
816+ {
817+ summary : "$SNAP_DATA source skipped" ,
818+ base : "core26" ,
819+ layout : " /opt/lib:\n bind: $SNAP_DATA/lib\n " ,
820+ },
821+ {
822+ summary : "$SNAP_COMMON source skipped" ,
823+ base : "core26" ,
824+ layout : " /opt/lib:\n bind: $SNAP_COMMON/lib\n " ,
825+ },
826+ } {
827+ s .checkSkeletonLayoutSource (c , tc )
828+ }
829+ }
830+
831+ func (s * packSuite ) TestCheckSkeletonLayoutSourceInvalid (c * C ) {
832+ for _ , tc := range []layoutSourceTestCase {
833+ {
834+ summary : "bind source missing" ,
835+ base : "core26" ,
836+ layout : " /opt/lib:\n bind: $SNAP/lib\n " ,
837+ errMatch : `layout "/opt/lib" source "\$SNAP/lib" does not exist` ,
838+ },
839+ {
840+ summary : "bind source is a file not directory" ,
841+ base : "core26" ,
842+ layout : " /opt/lib:\n bind: $SNAP/lib\n " ,
843+ files : []string {"lib" },
844+ errMatch : `layout "/opt/lib" source "\$SNAP/lib" must be a directory` ,
845+ },
846+ {
847+ summary : "bind-file source is a directory not file" ,
848+ base : "core26" ,
849+ layout : " /opt/foo.conf:\n bind-file: $SNAP/foo.conf\n " ,
850+ files : []string {"foo.conf/" },
851+ errMatch : `layout "/opt/foo.conf" source "\$SNAP/foo.conf" must be a file` ,
852+ },
853+ } {
854+ s .checkSkeletonLayoutSource (c , tc )
855+ }
856+ }
857+
858+ func (s * packSuite ) TestCheckSkeletonLayoutSourceOldBaseSkipped (c * C ) {
859+ for _ , base := range []string {"bare" , "core" , "core18" , "core20" , "core22" , "core24" } {
860+ s .checkSkeletonLayoutSource (c , layoutSourceTestCase {
861+ summary : "old base " + base ,
862+ base : base ,
863+ layout : " /opt/lib:\n bind: $SNAP/lib\n " ,
864+ })
865+ }
866+ }
0 commit comments