github.com/xyproto/u-root@v6.0.1-0.20200302025726-5528e0c77a3c+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  	var (
    43  		mp  *mount.MountPoint
    44  		err error
    45  	)
    46  	if os.Getenv("UROOT_USE_9P") == "1" {
    47  		mp, err = mount.Mount("tmpdir", "/testdata", "9p", "", 0)
    48  	} else {
    49  		mp, err = mount.Mount("/dev/sda1", "/testdata", "vfat", "", unix.MS_RDONLY)
    50  	}
    51  	if err != nil {
    52  		log.Fatalf("Failed to mount test directory: %v", err)
    53  	}
    54  	defer mp.Unmount(0) //nolint:errcheck
    55  
    56  	walkTests("/testdata/tests", func(path, pkgName string) {
    57  		ctx, cancel := context.WithTimeout(context.Background(), 25000*time.Millisecond)
    58  		defer cancel()
    59  
    60  		r, w, err := os.Pipe()
    61  		if err != nil {
    62  			log.Printf("Failed to get pipe: %v", err)
    63  			return
    64  		}
    65  
    66  		cmd := exec.CommandContext(ctx, path, "-test.v")
    67  		cmd.Stdin, cmd.Stderr = os.Stdin, os.Stderr
    68  
    69  		// Write to stdout for humans, write to w for the JSON converter.
    70  		//
    71  		// The test collector will gobble up JSON for statistics, and
    72  		// print non-JSON for humans to consume.
    73  		cmd.Stdout = io.MultiWriter(os.Stdout, w)
    74  
    75  		// Start test in its own dir so that testdata is available as a
    76  		// relative directory.
    77  		cmd.Dir = filepath.Dir(path)
    78  		if err := cmd.Start(); err != nil {
    79  			log.Printf("Failed to start %v: %v", path, err)
    80  			return
    81  		}
    82  
    83  		j := exec.CommandContext(ctx, "test2json", "-t", "-p", pkgName)
    84  		j.Stdin = r
    85  		j.Stdout, cmd.Stderr = os.Stdout, os.Stderr
    86  		if err := j.Start(); err != nil {
    87  			log.Printf("Failed to start test2json: %v", err)
    88  			return
    89  		}
    90  
    91  		// Don't do anything if the test fails. The log collector will
    92  		// deal with it. ¯\_(ツ)_/¯
    93  		cmd.Wait()
    94  		// Close the pipe so test2json will quit.
    95  		w.Close()
    96  		j.Wait()
    97  	})
    98  
    99  	log.Printf("GoTest Done")
   100  
   101  	unix.Reboot(unix.LINUX_REBOOT_CMD_POWER_OFF)
   102  }