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 }