github.com/ethersphere/bee/v2@v2.2.0/pkg/api/chunk_stream_test.go (about)

     1  // Copyright 2021 The Swarm 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 api_test
     6  
     7  import (
     8  	"bytes"
     9  	"net/http"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/ethersphere/bee/v2/pkg/api"
    14  	mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock"
    15  	"github.com/ethersphere/bee/v2/pkg/spinlock"
    16  	testingc "github.com/ethersphere/bee/v2/pkg/storage/testing"
    17  	mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock"
    18  	"github.com/ethersphere/bee/v2/pkg/swarm"
    19  	"github.com/gorilla/websocket"
    20  )
    21  
    22  // nolint:paralleltest
    23  func TestChunkUploadStream(t *testing.T) {
    24  	wsHeaders := http.Header{}
    25  	wsHeaders.Set(api.ContentTypeHeader, "application/octet-stream")
    26  	wsHeaders.Set(api.SwarmPostageBatchIdHeader, batchOkStr)
    27  
    28  	var (
    29  		storerMock               = mockstorer.New()
    30  		_, wsConn, _, chanStorer = newTestServer(t, testServerOptions{
    31  			Storer:       storerMock,
    32  			Post:         mockpost.New(mockpost.WithAcceptAll()),
    33  			WsPath:       "/chunks/stream",
    34  			WsHeaders:    wsHeaders,
    35  			DirectUpload: true,
    36  		})
    37  	)
    38  
    39  	t.Run("upload and verify", func(t *testing.T) {
    40  		chsToGet := []swarm.Chunk{}
    41  		for i := 0; i < 5; i++ {
    42  			ch := testingc.GenerateTestRandomChunk()
    43  
    44  			err := wsConn.SetWriteDeadline(time.Now().Add(time.Second))
    45  			if err != nil {
    46  				t.Fatal(err)
    47  			}
    48  
    49  			err = wsConn.WriteMessage(websocket.BinaryMessage, ch.Data())
    50  			if err != nil {
    51  				t.Fatal(err)
    52  			}
    53  
    54  			err = wsConn.SetReadDeadline(time.Now().Add(time.Second))
    55  			if err != nil {
    56  				t.Fatal(err)
    57  			}
    58  
    59  			mt, msg, err := wsConn.ReadMessage()
    60  			if err != nil {
    61  				t.Fatal(err)
    62  			}
    63  
    64  			if mt != websocket.BinaryMessage || !bytes.Equal(msg, api.SuccessWsMsg) {
    65  				t.Fatal("invalid response", mt, string(msg))
    66  			}
    67  
    68  			chsToGet = append(chsToGet, ch)
    69  		}
    70  
    71  		for _, c := range chsToGet {
    72  			err := spinlock.Wait(100*time.Millisecond, func() bool { return chanStorer.Has(c.Address()) })
    73  			if err != nil {
    74  				t.Fatal(err)
    75  			}
    76  		}
    77  	})
    78  
    79  	t.Run("close on incorrect msg", func(t *testing.T) {
    80  		err := wsConn.SetWriteDeadline(time.Now().Add(time.Second))
    81  		if err != nil {
    82  			t.Fatal(err)
    83  		}
    84  
    85  		err = wsConn.WriteMessage(websocket.TextMessage, []byte("incorrect msg"))
    86  		if err != nil {
    87  			t.Fatal(err)
    88  		}
    89  
    90  		err = wsConn.SetReadDeadline(time.Now().Add(time.Second))
    91  		if err != nil {
    92  			t.Fatal(err)
    93  		}
    94  
    95  		_, _, err = wsConn.ReadMessage()
    96  		if err == nil {
    97  			t.Fatal("expected failure on read")
    98  		}
    99  		// nolint:errorlint
   100  		if cerr, ok := err.(*websocket.CloseError); !ok {
   101  			t.Fatal("invalid error on read")
   102  		} else if cerr.Text != "invalid message" {
   103  			t.Fatalf("incorrect response on error, exp: (invalid message) got (%s)", cerr.Text)
   104  		}
   105  	})
   106  }