go-hep.org/x/hep@v0.38.1/groot/rcmd/copy_test.go (about)

     1  // Copyright ©2018 The go-hep Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package rcmd_test
     6  
     7  import (
     8  	"bytes"
     9  	"os"
    10  	"path/filepath"
    11  	"reflect"
    12  	"testing"
    13  
    14  	"go-hep.org/x/hep/groot"
    15  	"go-hep.org/x/hep/groot/rbase"
    16  	"go-hep.org/x/hep/groot/rcmd"
    17  	"go-hep.org/x/hep/groot/riofs"
    18  	"go-hep.org/x/hep/groot/root"
    19  	"go-hep.org/x/hep/groot/rtree"
    20  	"go-hep.org/x/hep/internal/diff"
    21  )
    22  
    23  func TestROOTCp(t *testing.T) {
    24  	dir, err := os.MkdirTemp("", "groot-root-cp-")
    25  	if err != nil {
    26  		t.Fatal(err)
    27  	}
    28  	defer os.RemoveAll(dir)
    29  
    30  	refname := filepath.Join(dir, "ref.root")
    31  	ref, err := groot.Create(refname)
    32  	if err != nil {
    33  		t.Fatalf("%+v", err)
    34  	}
    35  	defer ref.Close()
    36  
    37  	refs := []root.Object{
    38  		rbase.NewObjString("string1"),
    39  		rbase.NewObjString("string2"),
    40  		rbase.NewObjString("string3"),
    41  	}
    42  	keys := []string{
    43  		"key", "key-1", "str-3",
    44  	}
    45  
    46  	for i := range refs {
    47  		err := ref.Put(keys[i], refs[i])
    48  		if err != nil {
    49  			t.Fatalf("%+v", err)
    50  		}
    51  	}
    52  	{
    53  		subdir, err := riofs.Dir(ref).Mkdir("dir-1/dir-11")
    54  		if err != nil {
    55  			t.Fatalf("%+v", err)
    56  		}
    57  		obj := rbase.NewObjString("string111")
    58  		err = subdir.Put("str-111", obj)
    59  		if err != nil {
    60  			t.Fatalf("%+v", err)
    61  		}
    62  		keys = append(keys, "dir-1/dir-11/str-111")
    63  		refs = append(refs, obj)
    64  	}
    65  	{
    66  		subdir, err := riofs.Dir(ref).Mkdir("dir-1/dir-12")
    67  		if err != nil {
    68  			t.Fatalf("%+v", err)
    69  		}
    70  		obj := rbase.NewObjString("string121")
    71  		err = subdir.Put("str-121", obj)
    72  		if err != nil {
    73  			t.Fatalf("%+v", err)
    74  		}
    75  		keys = append(keys, "dir-1/dir-12/str-121")
    76  		refs = append(refs, obj)
    77  	}
    78  	{
    79  		subdir, err := riofs.Dir(ref).Mkdir("dir-2")
    80  		if err != nil {
    81  			t.Fatalf("%+v", err)
    82  		}
    83  
    84  		obj := rbase.NewObjString("string21")
    85  		err = subdir.Put("obj-21", obj)
    86  		if err != nil {
    87  			t.Fatalf("%+v", err)
    88  		}
    89  		keys = append(keys, "dir-2/obj-21")
    90  		refs = append(refs, obj)
    91  	}
    92  
    93  	err = ref.Close()
    94  	if err != nil {
    95  		t.Fatalf("%+v", err)
    96  	}
    97  
    98  	for _, tc := range []struct {
    99  		oname string
   100  		fname string
   101  		keys  []int
   102  	}{
   103  		{
   104  			oname: "out-all.root",
   105  			fname: refname,
   106  			keys:  []int{0, 1, 2, 3, 4, 5},
   107  		},
   108  		{
   109  			oname: "out-key.root",
   110  			fname: refname + ":key",
   111  			keys:  []int{0, 1},
   112  		},
   113  		{
   114  			oname: "out-key-star.root",
   115  			fname: refname + ":key.*",
   116  			keys:  []int{0, 1},
   117  		},
   118  		{
   119  			oname: "out-key-star2.root",
   120  			fname: refname + ":key-.*",
   121  			keys:  []int{1},
   122  		},
   123  		{
   124  			oname: "out-str10.root",
   125  			fname: refname + ":^/str",
   126  			keys:  []int{2},
   127  		},
   128  		{
   129  			oname: "out-str11.root",
   130  			fname: refname + ":/str",
   131  			keys:  []int{2, 3, 4},
   132  		},
   133  		{
   134  			oname: "out-str12.root",
   135  			fname: refname + ":str",
   136  			keys:  []int{2, 3, 4},
   137  		},
   138  		{
   139  			oname: "out-str20.root",
   140  			fname: refname + ":^/str.*",
   141  			keys:  []int{2},
   142  		},
   143  		{
   144  			oname: "out-str21.root",
   145  			fname: refname + ":/str.*",
   146  			keys:  []int{2, 3, 4},
   147  		},
   148  		{
   149  			oname: "out-str22.root",
   150  			fname: refname + ":str.*",
   151  			keys:  []int{2, 3, 4},
   152  		},
   153  		{
   154  			oname: "out-dir.root",
   155  			fname: refname + ":dir",
   156  			keys:  []int{3, 4, 5},
   157  		},
   158  		{
   159  			oname: "empty.root",
   160  			fname: refname + ":NONE.*",
   161  			keys:  []int{},
   162  		},
   163  	} {
   164  		t.Run(tc.oname, func(t *testing.T) {
   165  			oname := filepath.Join(dir, tc.oname)
   166  			err := rcmd.Copy(oname, []string{tc.fname})
   167  			if err != nil {
   168  				t.Fatalf("%+v", err)
   169  			}
   170  
   171  			f, err := groot.Open(oname)
   172  			if err != nil {
   173  				t.Fatalf("%+v", err)
   174  			}
   175  			defer f.Close()
   176  
   177  			gotKeys := 0
   178  			err = riofs.Walk(f, func(path string, obj root.Object, err error) error {
   179  				if err != nil {
   180  					return err
   181  				}
   182  				name := path[len(f.Name()):]
   183  				if name == "" {
   184  					return nil
   185  				}
   186  				if _, isdir := obj.(riofs.Directory); isdir {
   187  					return nil
   188  				}
   189  				gotKeys++
   190  				return nil
   191  			})
   192  			if err != nil {
   193  				t.Fatalf("could not count keys in output ROOT file: %+v", err)
   194  			}
   195  
   196  			if got, want := gotKeys, len(tc.keys); got != want {
   197  				t.Fatalf("invalid number of keys. got=%d, want=%d", got, want)
   198  			}
   199  
   200  			for _, i := range tc.keys {
   201  				v, err := riofs.Dir(f).Get(keys[i])
   202  				if err != nil {
   203  					t.Fatalf("%+v", err)
   204  				}
   205  
   206  				switch v := v.(type) {
   207  				case riofs.Directory:
   208  					if got, want := v.(root.Named).Name(), refs[i].(root.Named).Name(); got != want {
   209  						t.Fatalf(
   210  							"invalid value for %q:\ngot=%v\nwant=%v\n",
   211  							keys[i],
   212  							got, want,
   213  						)
   214  					}
   215  				default:
   216  					if !reflect.DeepEqual(v, refs[i]) {
   217  						t.Fatalf(
   218  							"invalid value for %q:\ngot=%v\nwant=%v\n",
   219  							keys[i],
   220  							v, refs[i],
   221  						)
   222  					}
   223  				}
   224  			}
   225  
   226  		})
   227  	}
   228  }
   229  
   230  func TestROOTCpTree(t *testing.T) {
   231  	dir, err := os.MkdirTemp("", "groot-root-cp-")
   232  	if err != nil {
   233  		t.Fatal(err)
   234  	}
   235  	defer os.RemoveAll(dir)
   236  
   237  	refname := filepath.Join(dir, "ref.root")
   238  	ref, err := groot.Create(refname)
   239  	if err != nil {
   240  		t.Fatalf("%+v", err)
   241  	}
   242  	defer ref.Close()
   243  
   244  	rdata := struct {
   245  		N    int32
   246  		I32s []int32 `groot:"i32s[N]"`
   247  	}{}
   248  
   249  	refdir, err := riofs.Dir(ref).Mkdir("dir1/dir11")
   250  	if err != nil {
   251  		t.Fatalf("could not create dir hierarchy: %+v", err)
   252  	}
   253  
   254  	rsrc, err := rtree.NewWriter(refdir, "mytree", rtree.WriteVarsFromStruct(&rdata))
   255  	if err != nil {
   256  		t.Fatal(err)
   257  	}
   258  	for i := range 5 {
   259  		rdata.N = int32(i)
   260  		rdata.I32s = make([]int32, i)
   261  		for j := range rdata.I32s {
   262  			rdata.I32s[j] = int32(i)
   263  		}
   264  
   265  		_, err = rsrc.Write()
   266  		if err != nil {
   267  			t.Fatalf("could not write event %d: %+v", i, err)
   268  		}
   269  	}
   270  
   271  	err = rsrc.Close()
   272  	if err != nil {
   273  		t.Fatalf("could not close src tree: %+v", err)
   274  	}
   275  
   276  	err = ref.Close()
   277  	if err != nil {
   278  		t.Fatalf("could not close ref file: %+v", err)
   279  	}
   280  
   281  	chkname := filepath.Join(dir, "chk.root")
   282  	err = rcmd.Copy(chkname, []string{refname + ":dir1/dir11/mytree"})
   283  	if err != nil {
   284  		t.Fatalf("could not copy tree: %+v", err)
   285  	}
   286  
   287  	want := new(bytes.Buffer)
   288  	err = rcmd.Dump(want, refname, true, nil)
   289  	if err != nil {
   290  		t.Fatalf("could not dump ref file %q: %+v", refname, err)
   291  	}
   292  
   293  	got := new(bytes.Buffer)
   294  	err = rcmd.Dump(got, chkname, true, nil)
   295  	if err != nil {
   296  		t.Fatalf("could not dump new file %q: %+v", chkname, err)
   297  	}
   298  
   299  	if got, want := got.String(), want.String(); got != want {
   300  		t.Fatalf("dumps differ:\n%s\n", diff.Format(got, want))
   301  	}
   302  }