Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

31 tests #37

Merged
merged 6 commits into from
Oct 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@

# Run our golang tests
go test ./... -race

# Run the perl script to look for function orders
.github/test-ordering.pl || exit 1
71 changes: 71 additions & 0 deletions .github/test-ordering.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/perl
#
# Trivial script to find *.go files, and ensure their
# functions are all defined in alphabetical order.
#
# Ignore "init" and any "BenchmarkXXX" functions.
#

use strict;
use warnings;

use File::Find;

# Failure count
my $failed = 0;

# Find all files beneath the current directory
find( { wanted => \&process, no_chdir => 1, follow => 0 }, '.' );

# Return the result as an exit code
exit $failed;


# Process a file
sub process
{
# Get the filename, and make sure it is a file.
my $file = $File::Find::name;
return unless ( $file =~ /.go$/ );

print "$file\n";

open( my $handle, "<", $file ) or
die "Failed to read $file: $!";

my @subs;

foreach my $line (<$handle>)
{
if ( $line =~ /^func\s+([^(]+)\(/ )
{
my $func = $1;

# Skip init
next if $func eq "init";

# Skip BenchmarkXXX
next if $func =~ /^Benchmark/;

# Record the function now.
push( @subs, $func );
}
}
close $handle;

# Is the list of functions sorted?
my @sorted = sort @subs;
my $len = $#sorted;

my $i = 0;
while ( $i < $len )
{
if ( $sorted[$i] ne $subs[$i] )
{
print "$sorted[$i] ne $subs[$i]\n";
$failed++;
}
$i++;

}
}
18 changes: 8 additions & 10 deletions builtins/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ package builtins
import (
"bufio"
"bytes"
"flag"
"fmt"
"math"
"math/rand"
Expand Down Expand Up @@ -542,7 +541,7 @@ func fileReadFn(env *env.Environment, args []primitive.Primitive) primitive.Prim
return primitive.String(string(data))
}

// fileStatFn implements (file:lines)
// fileStatFn implements (file:stat)
//
// Return value is (NAME SIZE UID GID MODE)
func fileStatFn(env *env.Environment, args []primitive.Primitive) primitive.Primitive {
Expand All @@ -564,16 +563,15 @@ func fileStatFn(env *env.Environment, args []primitive.Primitive) primitive.Prim
return primitive.Nil{}
}

var UID int
var GID int
// If we're not on Linux the Stat_t type won't be available,
// so we'd default to the current user.
UID := os.Getuid()
GID := os.Getgid()

// But if we can get the "real" values, then use them.
if stat, ok := info.Sys().(*syscall.Stat_t); ok {
UID = int(stat.Uid)
GID = int(stat.Gid)
} else {
// we are not in linux, this won't work anyway in windows,
// but maybe you want to log warnings
UID = os.Getuid()
GID = os.Getgid()
}

var res primitive.List
Expand Down Expand Up @@ -1068,7 +1066,7 @@ func shellFn(env *env.Environment, args []primitive.Primitive) primitive.Primiti

// If we're running a test-case we'll stop here, because
// fuzzing might run commands.
if flag.Lookup("test.v") != nil {
if os.Getenv("FUZZ") != "" {
return primitive.List{}
}

Expand Down
92 changes: 92 additions & 0 deletions builtins/builtins_shell_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//go:build !windows && !darwin
// +build !windows,!darwin

package builtins

import (
"os"
"strings"
"testing"

"github.com/skx/yal/primitive"
)

// TestShell tests shell - but only on Linux/Unix
func TestShell(t *testing.T) {

// calling with no argument
out := shellFn(ENV, []primitive.Primitive{})

// Will lead to an error
_, ok := out.(primitive.Error)
if !ok {
t.Fatalf("expected error, got %v", out)
}

// One argument, but the wrong type
out = shellFn(ENV, []primitive.Primitive{
primitive.Number(3),
})

var e primitive.Primitive
e, ok = out.(primitive.Error)
if !ok {
t.Fatalf("expected error, got %v", out)
}
if !strings.Contains(e.ToString(), "not a list") {
t.Fatalf("got error, but wrong one %v", out)
}

// Echo command to execute.
cmd := primitive.List{}
cmd = append(cmd, primitive.String("echo"))
cmd = append(cmd, primitive.String("foo"))
cmd = append(cmd, primitive.String("bar"))

// Run the command
res := shellFn(ENV, []primitive.Primitive{cmd})

// Response should be a list
lst, ok2 := res.(primitive.List)
if !ok2 {
t.Fatalf("expected (shell) to return a list, got %v", res)
}

// with two entries
if len(lst) != 2 {
t.Fatalf("expected (shell) result to have two entries, got %v", lst)
}

//
// Now: run a command that will fail
//
fail := primitive.List{}
fail = append(fail, primitive.String("/fdsf/fdsf/-path-not/exists"))

// Run the command
out = shellFn(ENV, []primitive.Primitive{fail})

// Will lead to an error
_, ok = out.(primitive.Error)
if !ok {
t.Fatalf("expected error, got %v", out)
}

//
// Now: Pretend we're running under a fuzzer
//
os.Setenv("FUZZ", "FUZZ")
res = shellFn(ENV, []primitive.Primitive{cmd})

// Response should still be a list
lst, ok2 = res.(primitive.List)
if !ok2 {
t.Fatalf("expected (shell) to return a list, got %v", res)
}

// with zero entries
if len(lst) != 0 {
t.Fatalf("expected (shell) result to have zero entries, got %v", lst)
}

}
Loading