github.com/cs3org/reva/v2@v2.27.7/pkg/test/vars.go (about)

     1  // Copyright 2018-2021 CERN
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  // In applying this license, CERN does not waive the privileges and immunities
    16  // granted to it by virtue of its status as an Intergovernmental Organization
    17  // or submit itself to any jurisdiction.
    18  
    19  package test
    20  
    21  import (
    22  	"bytes"
    23  	"errors"
    24  	"os"
    25  	"path"
    26  )
    27  
    28  const (
    29  	// TmpDirPattern is the pattern used for tmp folder creation
    30  	TmpDirPattern = "tmp-reva-"
    31  )
    32  
    33  // File struct represents a test file,
    34  // with a certain content. Its name is defined in TestDir
    35  type File struct {
    36  	Content string
    37  }
    38  
    39  // Dir struct represents a test dir, where each
    40  // key is the resource (Dir or File) name
    41  type Dir map[string]interface{}
    42  
    43  // CleanerFunc is a function to call after creating a TestDir
    44  type CleanerFunc func()
    45  
    46  // TmpDir creates a dir in the system temp folder that has
    47  // TmpDirPattern as prefix
    48  func TmpDir() (string, CleanerFunc, error) {
    49  	name, err := os.MkdirTemp("", TmpDirPattern)
    50  	if err != nil {
    51  		return "", nil, err
    52  	}
    53  
    54  	c := func() {
    55  		os.RemoveAll(name)
    56  	}
    57  
    58  	return name, c, nil
    59  }
    60  
    61  // NewTestDir creates the Dir structure in a local temporary folder
    62  func NewTestDir(src Dir) (tmpdir string, cleanup CleanerFunc, err error) {
    63  	tmpdir, cleanup, err = TmpDir()
    64  	if err != nil {
    65  		return
    66  	}
    67  	err = newTestDirFileRecursive(tmpdir, src)
    68  	return
    69  }
    70  
    71  // NewFile creates a new file given the path and the content
    72  func NewFile(path, content string) error {
    73  	file, err := os.Create(path)
    74  	if err != nil {
    75  		return err
    76  	}
    77  	_, err = file.Write([]byte(content))
    78  	if err != nil {
    79  		return err
    80  	}
    81  	return nil
    82  }
    83  
    84  func newTestDirFileRecursive(p string, res interface{}) error {
    85  	switch r := res.(type) {
    86  	case Dir:
    87  		err := os.MkdirAll(p, 0755)
    88  		if err != nil {
    89  			return err
    90  		}
    91  		for name, content := range r {
    92  			newPath := path.Join(p, name)
    93  			err := newTestDirFileRecursive(newPath, content)
    94  			if err != nil {
    95  				return err
    96  			}
    97  		}
    98  		return nil
    99  	case File:
   100  		return NewFile(p, r.Content)
   101  	default:
   102  		return errors.New("type not supported")
   103  	}
   104  }
   105  
   106  // checks if the two files have the same content
   107  func fileEquals(file1, file2 string) bool {
   108  	c1, _ := os.ReadFile(file1)
   109  	c2, _ := os.ReadFile(file2)
   110  	return bytes.Equal(c1, c2)
   111  }
   112  
   113  // DirEquals recursively verifies that the content of two dir is the same.
   114  // Two files are equals if the name and the content is equal, while two folders
   115  // are equal if the name is equal and the content is recursively equal.
   116  func DirEquals(dir1, dir2 string) bool {
   117  
   118  	l1, _ := os.ReadDir(dir1)
   119  	l2, _ := os.ReadDir(dir2)
   120  
   121  	if len(l1) != len(l2) {
   122  		return false
   123  	}
   124  
   125  	// here l1 and l2 have the same length
   126  	for i := range l1 {
   127  		r1, r2 := l1[i], l2[i]
   128  		if r1.Name() != r2.Name() {
   129  			return false
   130  		}
   131  
   132  		path1, path2 := path.Join(dir1, r1.Name()), path.Join(dir2, r2.Name())
   133  
   134  		switch {
   135  		case r1.Type().IsDir() && r2.Type().IsDir(): // both are dirs
   136  			if !DirEquals(path1, path2) {
   137  				return false
   138  			}
   139  		case r1.Type().IsRegular() && r2.Type().IsRegular(): // both are files
   140  			if !fileEquals(path1, path2) {
   141  				return false
   142  			}
   143  		default: // different resource type
   144  			return false
   145  		}
   146  
   147  	}
   148  	return true
   149  }