golang.org/x/sys@v0.20.1-0.20240517151509-673e0f94c16d/windows/mkwinsyscall/mkwinsyscall_test.go (about)

     1  // Copyright 2023 The Go 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  	"bytes"
     9  	"go/format"
    10  	"os"
    11  	"path/filepath"
    12  	"strings"
    13  	"testing"
    14  )
    15  
    16  func TestDLLFilenameEscaping(t *testing.T) {
    17  	tests := []struct {
    18  		name     string
    19  		filename string
    20  	}{
    21  		{"no escaping necessary", "kernel32"},
    22  		{"escape period", "windows.networking"},
    23  		{"escape dash", "api-ms-win-wsl-api-l1-1-0"},
    24  	}
    25  	for _, tt := range tests {
    26  		t.Run(tt.name, func(t *testing.T) {
    27  			// Write a made-up syscall into a temp file for testing.
    28  			const prefix = "package windows\n//sys Example() = "
    29  			const suffix = ".Example"
    30  			name := filepath.Join(t.TempDir(), "syscall.go")
    31  			if err := os.WriteFile(name, []byte(prefix+tt.filename+suffix), 0666); err != nil {
    32  				t.Fatal(err)
    33  			}
    34  
    35  			// Ensure parsing, generating, and formatting run without errors.
    36  			// This is good enough to show that escaping is working.
    37  			src, err := ParseFiles([]string{name})
    38  			if err != nil {
    39  				t.Fatal(err)
    40  			}
    41  			var buf bytes.Buffer
    42  			if err := src.Generate(&buf); err != nil {
    43  				t.Fatal(err)
    44  			}
    45  			if _, err := format.Source(buf.Bytes()); err != nil {
    46  				t.Log(buf.String())
    47  				t.Fatal(err)
    48  			}
    49  		})
    50  	}
    51  }
    52  
    53  func TestSyscallXGeneration(t *testing.T) {
    54  	tests := []struct {
    55  		name        string
    56  		wantsysfunc string
    57  		sig         string
    58  	}{
    59  		{
    60  			name:        "syscall with 2 params",
    61  			wantsysfunc: "syscall.Syscall",
    62  			sig:         "Example(a1 *uint16, a2 *uint16) = ",
    63  		},
    64  		{
    65  			name:        "syscall with 6 params",
    66  			wantsysfunc: "syscall.Syscall6",
    67  			sig:         "Example(a1 *uint, a2 *uint, a3 *uint, a4 *uint, a5 *uint, a6 *uint) = ",
    68  		},
    69  		{
    70  			name:        "syscall with 15 params",
    71  			wantsysfunc: "syscall.Syscall15",
    72  			sig: strings.ReplaceAll(`Example(a1 *uint, a2 *uint, a3 *uint, a4 *uint, a5 *uint, a6 *uint,
    73  						a7 *uint, a8 *uint, a9 *uint, a10 *uint, a11 *uint, a12 *uint,
    74  						a13 *uint, a14 *uint, a15 *uint) = `, "\n", ""),
    75  		},
    76  		{
    77  			name:        "syscall with 18 params",
    78  			wantsysfunc: "syscall.SyscallN",
    79  			sig: strings.ReplaceAll(`Example(a1 *uint, a2 *uint, a3 *uint, a4 *uint, a5 *uint, a6 *uint,
    80  						a7 *uint, a8 *uint, a9 *uint, a10 *uint, a11 *uint, a12 *uint,
    81  						a13 *uint, a14 *uint, a15 *uint, a16 *uint, a17 *uint, a18 *uint) = `, "\n", ""),
    82  		},
    83  	}
    84  	for _, tt := range tests {
    85  		t.Run(tt.name, func(t *testing.T) {
    86  			// Write the syscall into a temp file for testing.
    87  			prefix := "package windows\n//sys " + tt.sig
    88  			suffix := ".Example"
    89  			name := filepath.Join(t.TempDir(), "syscall.go")
    90  			if err := os.WriteFile(name, []byte(prefix+"example"+suffix), 0666); err != nil {
    91  				t.Fatal(err)
    92  			}
    93  
    94  			// Ensure parsing, generating, and formatting run without errors.
    95  			// This is good enough to show that escaping is working.
    96  			src, err := ParseFiles([]string{name})
    97  			if err != nil {
    98  				t.Fatal(err)
    99  			}
   100  			var buf bytes.Buffer
   101  			if err := src.Generate(&buf); err != nil {
   102  				t.Fatal(err)
   103  			}
   104  			if _, err := format.Source(buf.Bytes()); err != nil {
   105  				t.Fatal(err)
   106  			}
   107  
   108  			if !strings.Contains(buf.String(), tt.wantsysfunc+"(") {
   109  				t.Fatalf("expected syscall func %q in buffer %s", tt.wantsysfunc, buf.String())
   110  			}
   111  		})
   112  	}
   113  }