github.com/la5nta/wl2k-go@v0.11.8/fbb/wl2k_test.go (about)

     1  // Copyright 2015 Martin Hebnes Pedersen (LA5NTA). All rights reserved.
     2  // Use of this source code is governed by the MIT-license that can be
     3  // found in the LICENSE file.
     4  
     5  package fbb
     6  
     7  import (
     8  	"bufio"
     9  	"fmt"
    10  	"net"
    11  	"os"
    12  	"strings"
    13  	"testing"
    14  )
    15  
    16  //[WL2K-2.8.4.8-B2FWIHJM$]
    17  //Brentwood CMS >
    18  //	;FW: LA5NTA
    19  //	[RMS Express-1.2.35.0-B2FHM$]
    20  //	; WL2K DE LA5NTA (JO39EQ)
    21  //	FF
    22  //FQ
    23  
    24  func TestSessionP2P(t *testing.T) {
    25  	client, master := net.Pipe()
    26  
    27  	clientErr := make(chan error)
    28  	go func() {
    29  		s := NewSession("LA5NTA", "N0CALL", "JO39EQ", nil)
    30  		_, err := s.Exchange(client)
    31  		clientErr <- err
    32  	}()
    33  
    34  	masterErr := make(chan error)
    35  	go func() {
    36  		s := NewSession("N0CALL", "LA5NTA", "JO39EQ", nil)
    37  		s.IsMaster(true)
    38  		_, err := s.Exchange(master)
    39  		masterErr <- err
    40  	}()
    41  
    42  	if err := <-masterErr; err != nil {
    43  		t.Errorf("Master returned with error: %s", err)
    44  	}
    45  	if err := <-clientErr; err != nil {
    46  		t.Errorf("Client returned with error: %s", err)
    47  	}
    48  }
    49  
    50  func TestFWAuxOnlyExperiment(t *testing.T) {
    51  	os.Setenv("FW_AUX_ONLY_EXPERIMENT", "1")
    52  	defer os.Setenv("FW_AUX_ONLY_EXPERIMENT", "0")
    53  
    54  	client, master := net.Pipe()
    55  
    56  	clientErr := make(chan error)
    57  	go func() {
    58  		s := NewSession("LA5NTA", "N0CALL", "JO39EQ", nil)
    59  		s.AddAuxiliaryAddress(AddressFromString("EMCOMM-1@winlink.org"))
    60  		_, err := s.Exchange(client)
    61  		clientErr <- err
    62  	}()
    63  
    64  	masterErr := make(chan error)
    65  	go func() {
    66  		s := NewSession("N0CALL", "LA5NTA", "JO39EQ", nil)
    67  		s.IsMaster(true)
    68  		_, err := s.Exchange(master)
    69  		switch fw := s.RemoteForwarders(); {
    70  		case len(fw) != 1:
    71  			t.Errorf("unexpected FW count: %d", len(fw))
    72  		case fw[0].String() != "EMCOMM-1":
    73  			t.Errorf("unexpected FW address: %q", fw[0])
    74  		}
    75  		masterErr <- err
    76  	}()
    77  
    78  	if err := <-masterErr; err != nil {
    79  		t.Errorf("Master returned with error: %s", err)
    80  	}
    81  	if err := <-clientErr; err != nil {
    82  		t.Errorf("Client returned with error: %s", err)
    83  	}
    84  }
    85  
    86  func TestSessionCMS(t *testing.T) {
    87  	client, srv := net.Pipe()
    88  
    89  	cerrs := make(chan error)
    90  	go func() {
    91  		s := NewSession("LA5NTA", "LA1B-10", "JO39EQ", nil)
    92  		_, err := s.Exchange(client)
    93  		cerrs <- err
    94  	}()
    95  
    96  	fmt.Fprint(srv, "[WL2K-2.8.4.8-B2FWIHJM$]\r")
    97  	fmt.Fprint(srv, "Foobar should be ignored\r")
    98  	fmt.Fprint(srv, "Test CMS >\r")
    99  
   100  	expectLines := []string{
   101  		";FW: LA5NTA\r",
   102  		"[wl2kgo-0.1a-B2FHM$]\r",
   103  		"; LA1B-10 DE LA5NTA (JO39EQ)\r",
   104  		"FF\r",
   105  	}
   106  
   107  	// Read until FF
   108  	rd := bufio.NewReader(srv)
   109  	for i, expected := range expectLines {
   110  		line, _ := rd.ReadString('\r')
   111  		if line != expected {
   112  			line, expected = strings.TrimSpace(line), strings.TrimSpace(expected)
   113  			t.Fatalf("Unexpected line [%d]: Got '%s', expected '%s'.", i, line, expected)
   114  		}
   115  	}
   116  
   117  	fmt.Fprint(srv, "FQ\r")
   118  	srv.Close()
   119  
   120  	if err := <-cerrs; err != nil {
   121  		t.Errorf("Session exchange returned error: %s", err)
   122  	}
   123  }
   124  
   125  func TestSessionCMDWithMessage(t *testing.T) {
   126  	client, srv := net.Pipe()
   127  
   128  	cerrs := make(chan error)
   129  	go func() {
   130  		s := NewSession("LA5NTA", "LA1B-10", "JO39EQ", nil)
   131  		_, err := s.Exchange(client)
   132  		cerrs <- err
   133  	}()
   134  
   135  	fmt.Fprint(srv, "[WL2K-2.8.4.8-B2FWIHJM$]\r")
   136  	fmt.Fprint(srv, "Test CMS >\r")
   137  
   138  	expectLines := []string{
   139  		";FW: LA5NTA\r",
   140  		"[wl2kgo-0.1a-B2FHM$]\r",
   141  		"; LA1B-10 DE LA5NTA (JO39EQ)\r",
   142  		"FF\r",
   143  	}
   144  
   145  	// Read until FF
   146  	rd := bufio.NewReader(srv)
   147  	for i, expected := range expectLines {
   148  		line, _ := rd.ReadString('\r')
   149  		if line != expected {
   150  			line, expected = strings.TrimSpace(line), strings.TrimSpace(expected)
   151  			t.Fatalf("Unexpected line [%d]: Got '%s', expected '%s'.", i, line, expected)
   152  		}
   153  	}
   154  
   155  	// Send one proposal
   156  	fmt.Fprintf(srv, "FC EM TJKYEIMMHSRB 527 123 0\r")
   157  	fmt.Fprintf(srv, "F> 3b\r") // No more proposals + checksum
   158  
   159  	propAnswer, _ := rd.ReadString('\r')
   160  	if propAnswer != "FS =\r" {
   161  		t.Errorf("Expected 'FS =', got '%s'", propAnswer)
   162  	}
   163  	fmt.Fprintf(srv, "FF\r") // No more messages
   164  
   165  	if line, _ := rd.ReadString('\r'); line != "FQ\r" {
   166  		t.Errorf("Expected 'FQ', got '%s'", line)
   167  	}
   168  
   169  	if err := <-cerrs; err != nil {
   170  		t.Errorf("Session exchange returned error: %s", err)
   171  	}
   172  }
   173  
   174  func TestSessionCMSv4(t *testing.T) {
   175  	client, srv := net.Pipe()
   176  
   177  	cerrs := make(chan error)
   178  	go func() {
   179  		s := NewSession("LA5NTA", "LA1B-10", "JO39EQ", nil)
   180  		_, err := s.Exchange(client)
   181  		cerrs <- err
   182  	}()
   183  
   184  	fmt.Fprint(srv, "[WL2K-4.0-B2FWIHJM$]\r")
   185  	fmt.Fprint(srv, "Test CMS >\r")
   186  
   187  	expectLines := []string{
   188  		";FW: LA5NTA\r",
   189  		"[wl2kgo-0.1a-B2FHM$]\r",
   190  		"; LA1B-10 DE LA5NTA (JO39EQ)\r",
   191  		"FF\r",
   192  	}
   193  
   194  	// Read until FF
   195  	rd := bufio.NewReader(srv)
   196  	for i, expected := range expectLines {
   197  		line, _ := rd.ReadString('\r')
   198  		if line != expected {
   199  			line, expected = strings.TrimSpace(line), strings.TrimSpace(expected)
   200  			t.Fatalf("Unexpected line [%d]: Got '%s', expected '%s'.", i, line, expected)
   201  		}
   202  	}
   203  
   204  	// Send some CMS v4 ; lines
   205  	fmt.Fprintf(srv, ";PM: LA5NTA TJKYEIMMHSRB 123 martin.h.pedersen@gmail.com\r")
   206  	fmt.Fprintf(srv, ";WARNING: Foo bar baz\r")
   207  
   208  	// Send one proposal
   209  	fmt.Fprintf(srv, "FC EM TJKYEIMMHSRB 527 123 0\r")
   210  	fmt.Fprintf(srv, "F> 3b\r") // No more proposals + checksum
   211  
   212  	propAnswer, _ := rd.ReadString('\r')
   213  	if propAnswer != "FS =\r" {
   214  		t.Errorf("Expected 'FS =', got '%s'", propAnswer)
   215  	}
   216  
   217  	fmt.Fprintf(srv, ";WARNING: Foo bar baz\r") // One more CMS v4 ; line
   218  	fmt.Fprintf(srv, "FF\r")                    // No more messages
   219  
   220  	if line, _ := rd.ReadString('\r'); line != "FQ\r" {
   221  		t.Errorf("Expected 'FQ', got '%s'", line)
   222  	}
   223  
   224  	if err := <-cerrs; err != nil {
   225  		t.Errorf("Session exchange returned error: %s", err)
   226  	}
   227  }
   228  
   229  func TestSortProposals(t *testing.T) {
   230  	props := []*Proposal{
   231  		mustProposalWithSubject("Just a test"),
   232  		mustProposalWithSubject("Re://WL2K O/Very important"),
   233  		mustProposalWithSubject("//WL2K R/Read this sometime, or don't"),
   234  		mustProposalWithSubject("//WL2K P/ Pretty important"),
   235  		mustProposalWithSubject("//WL2K Z/The world is on fire!"),
   236  	}
   237  
   238  	sortProposals(props)
   239  
   240  	// Flash
   241  	if props[0].Title() != "//WL2K Z/The world is on fire!" {
   242  		t.Error("Flash precedence was not in order")
   243  	}
   244  	// Immediate
   245  	if props[1].Title() != "Re://WL2K O/Very important" {
   246  		t.Error("Immediate precedence was not in order")
   247  	}
   248  	// Priority
   249  	if props[2].Title() != "//WL2K P/ Pretty important" {
   250  		t.Error("Priority precedence was not in order")
   251  	}
   252  	// Everything else is Routine, so goes by increasing size
   253  	if props[3].Title() != "Just a test" {
   254  		t.Error("Routine precedence was not in order")
   255  	}
   256  	if props[4].Title() != "//WL2K R/Read this sometime, or don't" {
   257  		t.Error("Routine precedence was not in order")
   258  	}
   259  }
   260  
   261  func mustProposalWithSubject(subject string) *Proposal {
   262  	p, err := proposalWithSubject(subject)
   263  	if err != nil {
   264  		panic(err)
   265  	}
   266  	return p
   267  }
   268  
   269  func proposalWithSubject(subject string) (*Proposal, error) {
   270  	msg := NewMessage(Private, "N0CALL")
   271  	msg.AddTo("N0CALL")
   272  	msg.SetSubject(subject)
   273  	_ = msg.SetBody("Satisfies validation")
   274  	return msg.Proposal(BasicProposal)
   275  }