On Fri, Apr 10, 2020 at 3:37 PM 'K Richard Pixley' via golang-nuts <golang-nuts@googlegroups.com> wrote: > > I have some code. It uses ioutil.ReadDir which returns a possible error. > > My testing is at 99% code coverage because I can't figure out a way to > set up a situation in which os.Open succeeds on a directory, but > ioutil.ReadDir fails. > > I can get to 100% code coverage if I throw away the err rather than > testing for it and reporting it but that seems a bit... well... > disingenuous. I've looked down the calls to the kernel call > getdirentries but the only errno I can see being relevant to a go > program is EIO and I can't think of a way to force that to happen on a > real file system. > > I can imagine a fake file system created specifically for this purpose, > but that seems an awfully long way around the barn. > > How can I get to 100% code coverage? Or should I just give up on > finding a way to cover that last, single line of error handling code?
I'm not proud. Here is an example program for which os.Open(dirname) succeeds but ioutil.ReadDir(dirname) fails. You may have to adjust pathMax and nameMax for your system. Whether you actually want to use this technique is left to you. Ian -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAOyqgcVgKj1oBq6wj_bpS4zN6kZduVjAfP1NxTcnvpskPSx9NA%40mail.gmail.com.
package main import ( "fmt" "log" "io/ioutil" "os" "path/filepath" "strings" ) const pathMax = 4096 const nameMax = 256 func main() { tmpdir, err := ioutil.TempDir("", "readdir") if err != nil { log.Fatal(err) } defer os.RemoveAll(tmpdir) dirname := tmpdir for n := len(tmpdir); n + 10 < pathMax; n += nameMax { next := nameMax - 1 if limit := pathMax - n - 10; limit < next { next = limit } subdir := strings.Repeat("d", next) dirname = filepath.Join(dirname, subdir) if err := os.Mkdir(dirname, 0o755); err != nil { log.Fatal(err) } } if err := os.Chdir(dirname); err != nil { log.Fatal(err) } f, err := os.Create("thisPathNameIsTooLong") if err != nil { log.Fatal(err) } if err := f.Close(); err != nil { log.Fatal(err) } if err := os.Chdir(tmpdir); err != nil { log.Fatal(err) } d, err := os.Open(dirname) if err != nil { log.Fatal(err) } fmt.Printf("os.Open(%q) succeeded\n", dirname) d.Close() if infos, err := ioutil.ReadDir(dirname); err != nil { fmt.Printf("ioutil.ReadDir(%q) failed: %v\n", dirname, err) } else { fmt.Printf("ioutil.ReadDir(%q) returned\n", dirname) for _, info := range infos { fmt.Printf(" %s\n", info.Name()) } } }