Skip to content

Commit

Permalink
More minor test-case updates (#192)
Browse files Browse the repository at this point in the history
* More minor test-case updates

This pull-request adds a new configuration option "pause-on-newlines"
which allows automatic delays on newlines, which helps for some of
our test cases.

For example `mbasic2.in` contains:

```
  30 NEXT I
  LIST
  RUN
```

If we let the `LIST` run it will poll for keyboard input to see if
it should react to Ctrl-C, or similar, and that will swallow pending
input.  So we have to pause/pretend there is no input until that
completes.

But adding "`#LIST\n#RUN`" or similar feels fragile and confusing.

Pausing after every newline will make things simpler.

* Added test of easter-egg responses

* Removed some pauses and needless lines in our input text

* Restored test-coverage back to 100% of drv_file.go

* Remove Ctrl-M in favour of \r, and remove the #==sleep facility, now we no longer use it.

* More CCP-test added

* Updated to add new CCP test
  • Loading branch information
skx authored Feb 3, 2025
1 parent 6764caa commit b32bff9
Show file tree
Hide file tree
Showing 17 changed files with 138 additions and 113 deletions.
58 changes: 27 additions & 31 deletions consolein/drv_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package consolein

import (
"fmt"
"io"
"os"
"strings"
Expand All @@ -17,13 +18,8 @@ import (
//
// The input-driver is primarily designed for testing and automation.
// We make a tiny pause between our functions and for every input
// character that is "#" we sleep a single second.
//
// (We must pause at times because there are some commands that poll
// for console input and cancel, or otherwise process it. For example the C
// compiler will poll for input when linking and if we don't give it
// some artificial delays we might find our pending input is swallowed
// at random - depending on the speed of the host.)
// we allow some conditional support for changing the line-endings
// which are used when replaying the various test-cases.
type FileInput struct {

// content contains the content of the file we're returning
Expand Down Expand Up @@ -188,6 +184,11 @@ func (fi *FileInput) BlockForCharacterNoEcho() (byte, error) {

time.Sleep(fi.delaySmall)

// Ensure we block, of we're supposed to.
for !time.Now().After(fi.delayUntil) {
time.Sleep(fi.delaySmall)
}

// If we have to deal with \r\n instead of just \n handle that first.
if len(fi.fakeInput) > 0 {
c := fi.fakeInput[0]
Expand All @@ -202,10 +203,20 @@ func (fi *FileInput) BlockForCharacterNoEcho() (byte, error) {
x := fi.content[fi.offset]
fi.offset++

// If we're supposed to inject a fake Ctrl-M then
// we'll record that for the next time we're called.
// We've found a newline in our input.
//
// We allow newlines to be handled a couple of different
// ways, and optionally trigger a delay, so we'll have to
// handle that here.
//
if x == '\n' {

// Does we pause on newlines?
pause, pausePresent := fi.options["pause-on-newline"]
if pausePresent && pause == "true" {
fi.delayUntil = time.Now().Add(fi.delayLarge)
}

// Does newline handling have special config?
opt, ok := fi.options["newline"]

Expand All @@ -214,35 +225,20 @@ func (fi *FileInput) BlockForCharacterNoEcho() (byte, error) {
return x, nil
}

// Look at way we have been configured to return newlines.
switch opt {
case "n":
// newline: n -> just return \n
// newline: n -> just return "\n"
return x, nil
case "m":
// newline: m -> just return Ctrl-M
return '', nil
// newline: m -> just return "\r"
return '\r', nil
case "both":
// newline: both -> first return Ctrl-M then "\n"
// newline: both -> first return "\r" then "\n"
fi.fakeInput = "\n" + fi.fakeInput
return '', nil
return '\r', nil
default:
// newline: XXX - Ignore it.
return x, nil
}
}

// Also allow a sleep to happen. Sigh.
if x == '#' {
fi.delayUntil = time.Now().Add(fi.delayLarge)

// We skip past the character and return the next
// one. Unless this is the end of the buffer in
// which case we return null.
if fi.offset < len(fi.content) {
x = fi.content[fi.offset]
fi.offset++
} else {
x = 0x00
return x, fmt.Errorf("unknown setting 'newline:%s' in test-case", opt)
}
}

Expand Down
35 changes: 10 additions & 25 deletions consolein/drv_file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func TestFileSetup(t *testing.T) {
}
defer os.Remove(file.Name())

_, err = file.Write([]byte("newline: both\n--\n#hi\n#"))
_, err = file.Write([]byte("newline: both\n--\nhi\n"))
if err != nil {
t.Fatalf("failed to write to temporary file")
}
Expand All @@ -40,7 +40,7 @@ func TestFileSetup(t *testing.T) {
c := 0
str := ""

for c < 5 {
for c < 3 {
var out byte
out, err = ch.BlockForCharacterNoEcho()
if err != nil {
Expand All @@ -50,7 +50,7 @@ func TestFileSetup(t *testing.T) {

c++
}
if str != "hi\n"+string(byte(0x00)) {
if str != "hi" {
t.Fatalf("error in string, got '%v' '%s'", str, str)
}

Expand All @@ -59,6 +59,7 @@ func TestFileSetup(t *testing.T) {
}

// After we've read all the characters we should just get EOF
_, _ = ch.BlockForCharacterNoEcho()
c = 0
for c < 10 {
_, err = ch.BlockForCharacterNoEcho()
Expand Down Expand Up @@ -200,7 +201,7 @@ func TestNewlineN(t *testing.T) {
}
defer os.Remove(file.Name())

_, err = file.Write([]byte("newline: n\n--\nhi\n"))
_, err = file.Write([]byte("newline: n\npause-on-newline:true\n--\nhi\n"))
if err != nil {
t.Fatalf("failed to write to temporary file")
}
Expand Down Expand Up @@ -251,7 +252,7 @@ func TestNewlineM(t *testing.T) {
}
defer os.Remove(file.Name())

_, err = file.Write([]byte("newline: m\n--\nhi\n"))
_, err = file.Write([]byte("newline: m\npause-on-newline:false\n--\nhi\n"))
if err != nil {
t.Fatalf("failed to write to temporary file")
}
Expand Down Expand Up @@ -351,7 +352,7 @@ func TestNewlineBogus(t *testing.T) {
}
defer os.Remove(file.Name())

_, err = file.Write([]byte("newline: bogus\n--\nhi\n"))
_, err = file.Write([]byte("newline: bogus\n--\n\n"))
if err != nil {
t.Fatalf("failed to write to temporary file")
}
Expand All @@ -369,25 +370,9 @@ func TestNewlineBogus(t *testing.T) {
t.Fatalf("failed to setup driver %s", sErr.Error())
}

if !ch.PendingInput() {
t.Fatalf("expected pending input (a)")
}

c := 0
str := ""

for c < 3 {
var out byte
out, err = ch.BlockForCharacterNoEcho()
if err != nil {
t.Fatalf("failed to get character")
}
str += string(out)

c++
}
if str != "hi\n" {
t.Fatalf("error in string, got '%v' '%s'", str, str)
_, err = ch.BlockForCharacterNoEcho()
if err == nil {
t.Fatalf("expected to get an error, got none")
}
}

Expand Down
19 changes: 11 additions & 8 deletions test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,14 @@ The idea is that to write a new test there will be two files created:
## Configuration

We've had to had some configuration to the test-cases to work with assumptions, at the moment
the only real config is "newline":

* "n"
* A newline is \n
* "m"
* A newline is Ctrl-M
* "both"
* A newline is the pair "\n" "Ctrl-m", in that order.
the only real config options relate to newline handling.

* `newline` specifies which kind of line-endings to send:
* "n"
* A newline is \n
* "m"
* A newline is Ctrl-M
* "both"
* A newline is the pair "Ctrl-m" & "\n", in that order.
* `pause-on-newline:true`
* Will sleep for five seconds after sending a newline.
7 changes: 4 additions & 3 deletions test/bbcbasic1.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
# it won't react to keyboard input.
#
newline: both
pause-on-newline:true
--
B:
#BBCBASIC
#PRINT 1 + 2 * 3
#*BYE
BBCBASIC
PRINT 1 + 2 * 3
*BYE

EXIT
13 changes: 7 additions & 6 deletions test/bbcbasic2.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
# it won't react to keyboard input.
#
newline: both
pause-on-newline:true
--
B:
#BBCBASIC
#10 FOR I=1 TO 5
BBCBASIC
10 FOR I=1 TO 5
20 PRINT I,I*I
30 NEXT I
#LIST
#RUN
#*BYE
30 NEXT I
LIST
RUN
*BYE

EXIT
File renamed without changes.
File renamed without changes.
15 changes: 15 additions & 0 deletions test/ccp2.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#
# This is a more substantial CCP-test
#
--
A:!input
A:!ctrlc
B:
A:!output
A:!output null
A:
!output adm-3a
!hostcmd
!ccp ccp
!ccp ccpz
Exit
9 changes: 9 additions & 0 deletions test/ccp2.pat
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Input driver is set to
The Ctrl-C count is currently set to
Console driver is set to 'adm-3a'
Input driver changed from adm-3a to null.
Input driver changed from null to adm-3a.
The prefix for executing commands on the host is unset.
Running commands on the host is disabled.
CCP changed to ccp
CCP changed to ccpz
35 changes: 9 additions & 26 deletions test/echo.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,19 @@
# however the compiler, assembler, and linker all seem to poll
# for keyboard input - and if they see input they abort.
#
# So we have to use the "#" character in our runtime section, below,
# to pause execution and attempt to time things such that we don't
# block the execution and kill the test.
# So we have to either use "#" to block execution for a few seconds
# here or there, or do the same for each newline.
#
pause-on-newline:true
--
C:

ERA ECHO.ASM

ERA ECHO.O

ERA ECHO.COM

DIR ECHO.*


#echo


#CC ECHO


#AS ECHO


#LN ECHO.O C.LIB


#ECHO foo bar cake



# EXIT
echo
CC ECHO
AS ECHO
LN ECHO.O C.LIB
ECHO foo bar cake
EXIT
24 changes: 24 additions & 0 deletions test/lighthouse3.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#
# This test-case launches the lighthouse of doom game,
# and then plays it to completion.
#
# It also tests that the game starts, which was a problem in the
# past because our CP/M BIOS was located within a region of
# RAM the game used.
#
--
G:
LIHOUSE
f
DOWN
CALL ME
CALL STEVE
CALL POLICE
CALL RUBBLE
CALL SKYE
CALL RYDER
CALL GHOSTBUSTERS
QUIT
N

EXIT
6 changes: 6 additions & 0 deletions test/lighthouse3.pat
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Debbie Harry says 'hello'
[email protected]
lack of a functioning police force.
Who you gonna call?
No pup is too small, no job is too big
enjoying a nap
3 changes: 3 additions & 0 deletions test/mbasic1.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
# to be inserted with our newlines, otherwise
# it won't react to keyboard input.
#
# The pause here isn't as necessary as in mbasic2.
#
newline: both
pause-on-newline:true
--
B:
MBASIC
Expand Down
14 changes: 12 additions & 2 deletions test/mbasic2.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,24 @@
# The BBC BASIC interpreter needs the fake ^M
# to be inserted with our newlines, otherwise
# it won't react to keyboard input.
#
# We also have to pause on newlines, because otheriwse
# the "LIST" will poll for keyboard input and swallow
# some of the following characters.
#
# That will manifest itself as "LIST" working as expected
# but the next command being "N" showing a syntax error
# as the "RU" have been swallowed.
#
newline: both
pause-on-newline:true
--
B:
#MBASIC
MBASIC
10 FOR I=1 TO 5
20 PRINT I,I*I
30 NEXT I
#LIST
LIST
RUN
SYSTEM

Expand Down
Loading

0 comments on commit b32bff9

Please sign in to comment.