github.com/apptainer/singularity@v3.1.1+incompatible/internal/pkg/syecl/syecl_test.go (about)

     1  // Copyright (c) 2018, Sylabs Inc. All rights reserved.
     2  // This software is licensed under a 3-clause BSD license. Please consult the
     3  // LICENSE.md file distributed with the sources of this project regarding your
     4  // rights to use or distribute this software.
     5  
     6  package syecl
     7  
     8  import (
     9  	"io"
    10  	"io/ioutil"
    11  	"os"
    12  	"path/filepath"
    13  	"testing"
    14  )
    15  
    16  const (
    17  	KeyFP1 = "5994BE54C31CF1B5E1994F987C52CF6D055F072B"
    18  	KeyFP2 = "7064B1D6EFF01B1262FED3F03581D99FE87EAFD1"
    19  )
    20  
    21  var (
    22  	srcContainer1 = filepath.Join("testdata", "container1.sif")
    23  	srcContainer2 = filepath.Join("testdata", "container2.sif")
    24  	srcContainer3 = filepath.Join("testdata", "container3.sif")
    25  )
    26  
    27  var (
    28  	testEclFileName  string // pathname of the Ecl config file
    29  	testEclFileName2 string // pathname of the Ecl config file
    30  	testEclDirPath1  string // dirname of the first Ecl execgroup
    31  	testEclDirPath2  string // dirname of the second Ecl execgroup
    32  	testEclDirPath3  string // dirname of the third Ecl execgroup
    33  	testContainer1   string // pathname of the first test container
    34  	testContainer2   string // pathname of the second test container
    35  	testContainer3   string // pathname of the third test container
    36  	testContainer4   string // pathname of the forth test container
    37  )
    38  
    39  var testEclConfig = EclConfig{
    40  	Activated: true,
    41  	ExecGroups: []execgroup{
    42  		{"group1", "whitelist", "", []string{KeyFP1, KeyFP2}},
    43  		{"group2", "whitestrict", "", []string{KeyFP1, KeyFP2}},
    44  		{"group3", "blacklist", "", []string{KeyFP1}},
    45  	},
    46  }
    47  
    48  var testEclConfig2 = EclConfig{
    49  	Activated: true,
    50  	ExecGroups: []execgroup{
    51  		{"pathdup", "whitelist", "/tmp", nil},
    52  		{"pathdup", "whitelist", "/tmp", nil},
    53  	},
    54  }
    55  
    56  func TestAPutConfig(t *testing.T) {
    57  	err := PutConfig(testEclConfig, testEclFileName)
    58  	if err != nil {
    59  		t.Error(`PutConfig(testEclConfig, testEclFileName):`, err)
    60  	}
    61  	err = PutConfig(testEclConfig2, testEclFileName2)
    62  	if err != nil {
    63  		t.Error(`PutConfig(testEclConfig2, testEclFileName2):`, err)
    64  	}
    65  }
    66  
    67  func TestLoadConfig(t *testing.T) {
    68  	ecl, err := LoadConfig(testEclFileName)
    69  	if err != nil {
    70  		t.Error(`LoadConfig(testEclFileName):`, err)
    71  	}
    72  	if ecl.Activated == false {
    73  		t.Error("the ECL should be activated")
    74  	}
    75  	if ecl.ExecGroups[0].DirPath != testEclDirPath1 {
    76  		t.Error("the path was expected to be:", testEclDirPath1)
    77  	}
    78  	if ecl.ExecGroups[0].KeyFPs[0] != KeyFP1 {
    79  		t.Error("the entity was expected to be:", KeyFP1)
    80  	}
    81  }
    82  
    83  func TestValidateConfig(t *testing.T) {
    84  	// Validate properly formed config file
    85  	ecl, err := LoadConfig(testEclFileName)
    86  	if err != nil {
    87  		t.Error(`LoadConfig(testEclFileName):`, err)
    88  	}
    89  	if err = ecl.ValidateConfig(); err != nil {
    90  		t.Error(`ecl.ValidateConfig():`, err)
    91  	}
    92  
    93  	// Validate config file with duplicated dirpaths
    94  	ecl, err = LoadConfig(testEclFileName2)
    95  	if err != nil {
    96  		t.Error(`LoadConfig(testEclFileName2):`, err)
    97  	}
    98  	if err = ecl.ValidateConfig(); err == nil {
    99  		t.Error(`ecl.ValidateConfig(): Should have detected duplicated dirpaths`, err)
   100  	}
   101  }
   102  
   103  func TestShouldRun(t *testing.T) {
   104  	ecl, err := LoadConfig(testEclFileName)
   105  	if err != nil {
   106  		t.Error(`LoadConfig(testEclFileName):`, err)
   107  	}
   108  
   109  	if err = ecl.ValidateConfig(); err != nil {
   110  		t.Error(`ecl.ValidateConfig():`, err)
   111  	}
   112  
   113  	// check container1 authorization
   114  	run, err := ecl.ShouldRun(testContainer1)
   115  	if err != nil {
   116  		t.Error(`ecl.ShouldRun(testContainer1):`, err)
   117  	}
   118  	if !run {
   119  		t.Error(testContainer1, "should be allowed to run")
   120  	}
   121  	// check container2 authorization
   122  	run, err = ecl.ShouldRun(testContainer2)
   123  	if err != nil {
   124  		t.Error(`ecl.ShouldRun(testContainer2):`, err)
   125  	}
   126  	if !run {
   127  		t.Error(testContainer2, "should be allowed to run")
   128  	}
   129  	// check container3 authorization (fails with KeyFP)
   130  	run, err = ecl.ShouldRun(testContainer3)
   131  	if err == nil || run == true {
   132  		t.Error(testContainer3, "should NOT be allowed to run")
   133  	}
   134  	// check srcContainer1 authorization (fails with dirpath)
   135  	run, err = ecl.ShouldRun(srcContainer1)
   136  	if err == nil || run == true {
   137  		t.Error(srcContainer1, "should NOT be allowed to run")
   138  	}
   139  	// check container4 authorization (fails with blacklist)
   140  	run, err = ecl.ShouldRun(testContainer4)
   141  	if err == nil || run == true {
   142  		t.Error(testContainer4, "should NOT be allowed to run")
   143  	}
   144  
   145  	// in this second round of tests, set DirPath to "", and test container in testdata/
   146  	ecl.ExecGroups[0].DirPath = ""
   147  	ecl.ExecGroups[1].DirPath = ""
   148  
   149  	// check container1 authorization (outside of defined dirpath)
   150  	run, err = ecl.ShouldRun(srcContainer1)
   151  	if err != nil {
   152  		t.Error(`ecl.ShouldRun(srcContainer1):`, err)
   153  	}
   154  	if !run {
   155  		t.Error(srcContainer1, "should be allowed to run")
   156  	}
   157  }
   158  
   159  func copyFile(dst, src string) error {
   160  	s, err := os.Open(src)
   161  	if err != nil {
   162  		return err
   163  	}
   164  	defer s.Close()
   165  
   166  	d, err := os.Create(dst)
   167  	if err != nil {
   168  		return err
   169  	}
   170  
   171  	if _, err := io.Copy(d, s); err != nil {
   172  		d.Close()
   173  		return err
   174  	}
   175  
   176  	return d.Close()
   177  }
   178  
   179  func setup() error {
   180  	// Use TempFile to create a placeholder for the ECL config test files
   181  	tmpfile, err := ioutil.TempFile("", "eclconfig-test")
   182  	if err != nil {
   183  		return nil
   184  	}
   185  	testEclFileName = tmpfile.Name()
   186  	tmpfile.Close()
   187  
   188  	tmpfile, err = ioutil.TempFile("", "eclconfig2-test")
   189  	if err != nil {
   190  		return nil
   191  	}
   192  	testEclFileName2 = tmpfile.Name()
   193  	tmpfile.Close()
   194  
   195  	// Create three directories where we put test containers
   196  	testEclDirPath1, err = ioutil.TempDir("", "ecldir1-")
   197  	if err != nil {
   198  		return err
   199  	}
   200  
   201  	testEclDirPath2, err = ioutil.TempDir("", "ecldir2-")
   202  	if err != nil {
   203  		return err
   204  	}
   205  
   206  	testEclDirPath3, err = ioutil.TempDir("", "ecldir3-")
   207  	if err != nil {
   208  		return err
   209  	}
   210  
   211  	// Set the just created Dirpaths in the EclConfig struct to marshal
   212  	testEclConfig.ExecGroups[0].DirPath = testEclDirPath1
   213  	testEclConfig.ExecGroups[1].DirPath = testEclDirPath2
   214  	testEclConfig.ExecGroups[2].DirPath = testEclDirPath3
   215  
   216  	// prepare and copy test containers from testdata/* to their test dirpaths
   217  	testContainer1 = filepath.Join(testEclDirPath1, filepath.Base(srcContainer1))
   218  	if err := copyFile(testContainer1, srcContainer1); err != nil {
   219  		return err
   220  	}
   221  	testContainer2 = filepath.Join(testEclDirPath2, filepath.Base(srcContainer2))
   222  	if err := copyFile(testContainer2, srcContainer2); err != nil {
   223  		return err
   224  	}
   225  	testContainer3 = filepath.Join(testEclDirPath2, filepath.Base(srcContainer3))
   226  	if err := copyFile(testContainer3, srcContainer3); err != nil {
   227  		return err
   228  	}
   229  	testContainer4 = filepath.Join(testEclDirPath3, filepath.Base(srcContainer3))
   230  	return copyFile(testContainer4, srcContainer3)
   231  }
   232  
   233  func shutdown() {
   234  	os.Remove(testEclFileName)
   235  	os.Remove(testEclFileName2)
   236  	os.RemoveAll(testEclDirPath1)
   237  	os.RemoveAll(testEclDirPath2)
   238  	os.RemoveAll(testEclDirPath3)
   239  }
   240  
   241  func TestMain(m *testing.M) {
   242  	if err := setup(); err != nil {
   243  		shutdown()
   244  		os.Exit(2)
   245  	}
   246  	ret := m.Run()
   247  	shutdown()
   248  	os.Exit(ret)
   249  }