github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/integration/testcmd/gotest/uinit/gotest.go (about)

     1  // Copyright 2018 the u-root 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 main
     6  
     7  import (
     8  	"context"
     9  	"io"
    10  	"log"
    11  	"os"
    12  	"os/exec"
    13  	"path/filepath"
    14  	"strings"
    15  	"time"
    16  
    17  	"github.com/u-root/u-root/pkg/mount"
    18  	"golang.org/x/sys/unix"
    19  )
    20  
    21  func walkTests(testRoot string, fn func(string, string)) error {
    22  	return filepath.Walk(testRoot, func(path string, info os.FileInfo, err error) error {
    23  		if !info.Mode().IsRegular() || !strings.HasSuffix(path, ".test") || err != nil {
    24  			return nil
    25  		}
    26  		t2, err := filepath.Rel(testRoot, path)
    27  		if err != nil {
    28  			return err
    29  		}
    30  		pkgName := filepath.Dir(t2)
    31  
    32  		fn(path, pkgName)
    33  		return nil
    34  	})
    35  }
    36  
    37  // Mount a vfat volume and run the tests within.
    38  func main() {
    39  	if err := os.MkdirAll("/testdata", 0755); err != nil {
    40  		log.Fatalf("Couldn't create testdata: %v", err)
    41  	}
    42  
    43  	var (
    44  		mp  *mount.MountPoint
    45  		err error
    46  	)
    47  	if os.Getenv("UROOT_USE_9P") == "1" {
    48  		mp, err = mount.Mount("tmpdir", "/testdata", "9p", "", 0)
    49  	} else {
    50  		mp, err = mount.Mount("/dev/sda1", "/testdata", "vfat", "", unix.MS_RDONLY)
    51  	}
    52  	if err != nil {
    53  		log.Fatalf("Failed to mount test directory: %v", err)
    54  	}
    55  	defer mp.Unmount(0) //nolint:errcheck
    56  
    57  	walkTests("/testdata/tests", func(path, pkgName string) {
    58  		ctx, cancel := context.WithTimeout(context.Background(), 25000*time.Millisecond)
    59  		defer cancel()
    60  
    61  		r, w, err := os.Pipe()
    62  		if err != nil {
    63  			log.Printf("Failed to get pipe: %v", err)
    64  			return
    65  		}
    66  
    67  		cmd := exec.CommandContext(ctx, path, "-test.v")
    68  		cmd.Stdin, cmd.Stderr = os.Stdin, os.Stderr
    69  
    70  		// Write to stdout for humans, write to w for the JSON converter.
    71  		//
    72  		// The test collector will gobble up JSON for statistics, and
    73  		// print non-JSON for humans to consume.
    74  		cmd.Stdout = io.MultiWriter(os.Stdout, w)
    75  
    76  		// Start test in its own dir so that testdata is available as a
    77  		// relative directory.
    78  		cmd.Dir = filepath.Dir(path)
    79  		if err := cmd.Start(); err != nil {
    80  			log.Printf("Failed to start %v: %v", path, err)
    81  			return
    82  		}
    83  
    84  		j := exec.CommandContext(ctx, "test2json", "-t", "-p", pkgName)
    85  		j.Stdin = r
    86  		j.Stdout, cmd.Stderr = os.Stdout, os.Stderr
    87  		if err := j.Start(); err != nil {
    88  			log.Printf("Failed to start test2json: %v", err)
    89  			return
    90  		}
    91  
    92  		// Don't do anything if the test fails. The log collector will
    93  		// deal with it. ¯\_(ツ)_/¯
    94  		cmd.Wait()
    95  		// Close the pipe so test2json will quit.
    96  		w.Close()
    97  		j.Wait()
    98  	})
    99  
   100  	log.Printf("GoTest Done")
   101  
   102  	unix.Reboot(unix.LINUX_REBOOT_CMD_POWER_OFF)
   103  }