You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

851 lines
22 KiB

  1. // Copyright 2016 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package internal
  15. import (
  16. "bytes"
  17. "context"
  18. "errors"
  19. "fmt"
  20. "io"
  21. "log"
  22. "sync"
  23. "testing"
  24. "google.golang.org/grpc"
  25. pb "google.golang.org/genproto/googleapis/bytestream"
  26. )
  27. const (
  28. testName = "testName"
  29. testData = "0123456789"
  30. )
  31. var (
  32. setupServerOnce sync.Once
  33. server *Server
  34. )
  35. func TestNewServerWithInvalidInputs(t *testing.T) {
  36. _, err := NewServer(grpc.NewServer(), nil, nil)
  37. if err == nil {
  38. t.Fatal("NewServer(nil, nil) should not succeed")
  39. }
  40. }
  41. func TestServerWrite(t *testing.T) {
  42. testCases := []struct {
  43. name string
  44. writeHandler WriteHandler
  45. input []interface{}
  46. writeCount int
  47. allowEmptyCommits bool
  48. allowOverwrite bool
  49. wantErr bool
  50. wantResponse int
  51. }{
  52. {
  53. name: "empty resource name",
  54. writeHandler: &TestWriteHandler{},
  55. input: []interface{}{
  56. &pb.WriteRequest{
  57. FinishWrite: true,
  58. Data: []byte(testData),
  59. },
  60. },
  61. writeCount: 1,
  62. wantErr: true,
  63. wantResponse: 0,
  64. }, {
  65. name: "Recv returns io.EOF",
  66. writeHandler: &TestWriteHandler{},
  67. input: []interface{}{
  68. io.EOF,
  69. },
  70. writeCount: 1,
  71. wantErr: false,
  72. wantResponse: 0,
  73. }, {
  74. name: "Recv returns error, 0 WriteRequests",
  75. writeHandler: &TestWriteHandler{},
  76. input: []interface{}{
  77. errors.New("Recv returns error, 0 WriteRequests"),
  78. },
  79. writeCount: 1,
  80. wantErr: true,
  81. wantResponse: 0,
  82. }, {
  83. name: "simple test",
  84. writeHandler: &TestWriteHandler{},
  85. input: []interface{}{
  86. &pb.WriteRequest{
  87. ResourceName: testName,
  88. WriteOffset: 0,
  89. FinishWrite: true,
  90. Data: []byte(testData),
  91. },
  92. io.EOF,
  93. },
  94. writeCount: 1,
  95. wantResponse: 1,
  96. }, {
  97. name: "Recv returns error, 1 WriteRequests",
  98. writeHandler: &TestWriteHandler{},
  99. input: []interface{}{
  100. &pb.WriteRequest{
  101. ResourceName: testName,
  102. WriteOffset: 0,
  103. FinishWrite: false,
  104. Data: []byte(testData),
  105. },
  106. errors.New("Recv returns error, 1 WriteRequests"),
  107. },
  108. writeCount: 1,
  109. wantErr: true,
  110. wantResponse: 0,
  111. }, {
  112. name: "attempt to overwrite the same name",
  113. writeHandler: &TestWriteHandler{},
  114. input: []interface{}{
  115. &pb.WriteRequest{
  116. ResourceName: testName,
  117. WriteOffset: 0,
  118. FinishWrite: true,
  119. Data: []byte(testData),
  120. },
  121. io.EOF,
  122. &pb.WriteRequest{
  123. ResourceName: testName,
  124. WriteOffset: 0,
  125. FinishWrite: true,
  126. Data: []byte(testData),
  127. },
  128. },
  129. writeCount: 2,
  130. wantErr: true,
  131. wantResponse: 1,
  132. }, {
  133. name: "overwrite with the same name + AllowOverwrite",
  134. writeHandler: &TestWriteHandler{},
  135. input: []interface{}{
  136. &pb.WriteRequest{
  137. ResourceName: testName,
  138. WriteOffset: 0,
  139. FinishWrite: true,
  140. Data: []byte(testData),
  141. },
  142. io.EOF,
  143. &pb.WriteRequest{
  144. ResourceName: testName,
  145. WriteOffset: 0,
  146. FinishWrite: true,
  147. Data: []byte(testData),
  148. },
  149. io.EOF,
  150. },
  151. writeCount: 2,
  152. allowOverwrite: true,
  153. wantResponse: 2,
  154. }, {
  155. name: "two WriteRequests - 1st is empty",
  156. writeHandler: &TestWriteHandler{},
  157. input: []interface{}{
  158. &pb.WriteRequest{
  159. ResourceName: testName,
  160. WriteOffset: 0,
  161. FinishWrite: false,
  162. Data: nil,
  163. },
  164. &pb.WriteRequest{
  165. ResourceName: testName,
  166. WriteOffset: 0,
  167. FinishWrite: true,
  168. Data: []byte(testData),
  169. },
  170. io.EOF,
  171. },
  172. writeCount: 1,
  173. wantResponse: 1,
  174. allowEmptyCommits: true,
  175. }, {
  176. name: "two WriteRequests - 2nd is empty",
  177. writeHandler: &TestWriteHandler{},
  178. input: []interface{}{
  179. &pb.WriteRequest{
  180. ResourceName: testName,
  181. WriteOffset: 0,
  182. FinishWrite: false,
  183. Data: []byte(testData),
  184. },
  185. &pb.WriteRequest{
  186. ResourceName: testName,
  187. WriteOffset: int64(len(testData)),
  188. FinishWrite: true,
  189. Data: nil,
  190. },
  191. io.EOF,
  192. },
  193. writeCount: 1,
  194. wantResponse: 1,
  195. }, {
  196. name: "two WriteRequests - all empty",
  197. writeHandler: &TestWriteHandler{},
  198. input: []interface{}{
  199. &pb.WriteRequest{
  200. ResourceName: testName,
  201. WriteOffset: 0,
  202. FinishWrite: false,
  203. Data: nil,
  204. },
  205. &pb.WriteRequest{
  206. ResourceName: testName,
  207. WriteOffset: 0,
  208. FinishWrite: true,
  209. Data: nil,
  210. },
  211. },
  212. writeCount: 1,
  213. wantErr: true,
  214. wantResponse: 1,
  215. allowEmptyCommits: true,
  216. }, {
  217. name: "two WriteRequests - varying offset",
  218. writeHandler: &TestWriteHandler{},
  219. input: []interface{}{
  220. &pb.WriteRequest{
  221. ResourceName: testName,
  222. WriteOffset: 100,
  223. FinishWrite: false,
  224. Data: []byte(testData),
  225. },
  226. &pb.WriteRequest{
  227. ResourceName: testName,
  228. WriteOffset: 100 + int64(len(testData)),
  229. FinishWrite: true,
  230. Data: []byte(testData),
  231. },
  232. io.EOF,
  233. },
  234. writeCount: 1,
  235. wantResponse: 1,
  236. }, {
  237. name: "two WriteRequests - disjoint offset",
  238. writeHandler: &TestWriteHandler{},
  239. input: []interface{}{
  240. &pb.WriteRequest{
  241. ResourceName: testName,
  242. WriteOffset: 100,
  243. FinishWrite: false,
  244. Data: []byte(testData),
  245. },
  246. &pb.WriteRequest{
  247. ResourceName: testName,
  248. WriteOffset: 200,
  249. FinishWrite: true,
  250. Data: []byte(testData),
  251. },
  252. },
  253. writeCount: 1,
  254. wantErr: true,
  255. wantResponse: 0,
  256. }, {
  257. name: "fails with UngettableWriteHandler",
  258. writeHandler: &UngettableWriteHandler{},
  259. input: []interface{}{
  260. &pb.WriteRequest{
  261. ResourceName: testName,
  262. WriteOffset: 0,
  263. FinishWrite: true,
  264. Data: []byte(testData),
  265. },
  266. },
  267. writeCount: 1,
  268. wantErr: true,
  269. }, {
  270. name: "fails with UnwritableWriteHandler",
  271. writeHandler: &UnwritableWriteHandler{},
  272. input: []interface{}{
  273. &pb.WriteRequest{
  274. ResourceName: testName,
  275. WriteOffset: 0,
  276. FinishWrite: true,
  277. Data: []byte(testData),
  278. },
  279. },
  280. writeCount: 1,
  281. wantErr: true,
  282. }, {
  283. name: "fails with UnclosableWriteHandler",
  284. writeHandler: &UnclosableWriteHandler{},
  285. input: []interface{}{
  286. &pb.WriteRequest{
  287. ResourceName: testName,
  288. WriteOffset: 0,
  289. FinishWrite: true,
  290. Data: []byte(testData),
  291. },
  292. },
  293. writeCount: 1,
  294. wantErr: true,
  295. wantResponse: 1,
  296. }, {
  297. name: "fails with nil WriteHandler",
  298. writeHandler: nil,
  299. input: []interface{}{
  300. &pb.WriteRequest{
  301. ResourceName: testName,
  302. WriteOffset: 0,
  303. FinishWrite: true,
  304. Data: []byte(testData),
  305. },
  306. },
  307. writeCount: 1,
  308. wantErr: true,
  309. },
  310. }
  311. ctx := context.Background()
  312. for _, tc := range testCases {
  313. readHandler := &TestReadHandler{}
  314. if tc.writeHandler != nil {
  315. readHandler = nil
  316. }
  317. setupServer(readHandler, tc.writeHandler)
  318. server.AllowOverwrite = tc.allowOverwrite
  319. var requestCount, responseCount int
  320. var err error
  321. for i := 0; i < tc.writeCount; i++ {
  322. err = server.rpc.Write(&fakeWriteServerImpl{
  323. ctx: ctx,
  324. receiver: func() (*pb.WriteRequest, error) {
  325. if requestCount >= len(tc.input) {
  326. t.Fatalf("%s: got %d call(s) to Recv, want %d from len(input)", tc.name, requestCount+1, len(tc.input))
  327. }
  328. v := tc.input[requestCount]
  329. requestCount++
  330. request, ok := v.(*pb.WriteRequest)
  331. if ok {
  332. return request, nil
  333. }
  334. err, ok := v.(error)
  335. if !ok {
  336. t.Fatalf("%s: unknown input: %v", tc.name, v)
  337. }
  338. return nil, err
  339. },
  340. sender: func(response *pb.WriteResponse) error {
  341. if !tc.allowEmptyCommits && response.CommittedSize == 0 {
  342. t.Fatalf("%s: invalid response: WriteResponse %v", tc.name, response)
  343. }
  344. responseCount++
  345. return nil
  346. },
  347. })
  348. gotErr := (err != nil)
  349. if i+1 < tc.writeCount {
  350. if gotErr {
  351. t.Errorf("%s: Write got err=%v, wantErr=%t, but on Write[%d/%d]. Error should not happen until last call to Write.", tc.name, err, tc.wantErr, i+1, tc.writeCount)
  352. break // The t.Errorf conditions below may erroneously fire, pay them no mind.
  353. }
  354. } else if gotErr != tc.wantErr {
  355. t.Errorf("%s: Write got err=%v, wantErr=%t", tc.name, err, tc.wantErr)
  356. break // The t.Errorf conditions below may erroneously fire, pay them no mind.
  357. }
  358. }
  359. if requestCount != len(tc.input) {
  360. t.Errorf("%s: got %d call(s) to Recv, want %d", tc.name, requestCount, len(tc.input))
  361. }
  362. if responseCount != tc.wantResponse {
  363. t.Errorf("%s: got %d call(s) to SendProto, want %d", tc.name, responseCount, tc.wantResponse)
  364. }
  365. }
  366. }
  367. func TestServerWrite_SendAndCloseError(t *testing.T) {
  368. const (
  369. wantRequest = 2
  370. wantResponse = 1
  371. )
  372. ctx := context.Background()
  373. setupServer(nil, &TestWriteHandler{})
  374. var requestCount, responseCount int
  375. err := server.rpc.Write(&fakeWriteServerImpl{
  376. ctx: ctx,
  377. receiver: func() (*pb.WriteRequest, error) {
  378. if requestCount >= wantRequest {
  379. t.Fatalf("got %d call(s) to Recv, want %d", requestCount+1, wantRequest)
  380. }
  381. requestCount++
  382. return &pb.WriteRequest{
  383. ResourceName: testName,
  384. WriteOffset: 0,
  385. FinishWrite: true,
  386. Data: []byte(testData),
  387. }, nil
  388. },
  389. sender: func(response *pb.WriteResponse) error {
  390. responseCount++
  391. return errors.New("TestServerWrite SendProto error")
  392. },
  393. })
  394. if err == nil {
  395. t.Errorf("Write should have failed, but succeeded")
  396. }
  397. if requestCount != wantRequest {
  398. t.Errorf("got %d call(s) to Recv, want %d", requestCount, wantRequest)
  399. }
  400. if responseCount != wantResponse {
  401. t.Errorf("got %d call(s) to SendProto, want %d", responseCount, wantResponse)
  402. }
  403. }
  404. func TestQueryWriteStatus(t *testing.T) {
  405. testCases := []struct {
  406. name string
  407. existingName string
  408. requestName string
  409. wantErr bool
  410. }{
  411. {
  412. name: "existing name should work",
  413. existingName: testName,
  414. requestName: testName,
  415. }, {
  416. name: "missing name should break",
  417. existingName: testName,
  418. requestName: "invalidName",
  419. wantErr: true,
  420. },
  421. }
  422. ctx := context.Background()
  423. for _, tc := range testCases {
  424. setupServer(nil, &TestWriteHandler{})
  425. server.status[tc.existingName] = &pb.QueryWriteStatusResponse{}
  426. _, err := server.rpc.QueryWriteStatus(ctx, &pb.QueryWriteStatusRequest{
  427. ResourceName: tc.requestName,
  428. })
  429. if gotErr := (err != nil); gotErr != tc.wantErr {
  430. t.Errorf("%s: QueryWriteStatus(%q) got err=%v, wantErr=%t", tc.name, tc.requestName, err, tc.wantErr)
  431. }
  432. }
  433. }
  434. func TestServerRead(t *testing.T) {
  435. testCases := []struct {
  436. name string
  437. readHandler ReadHandler
  438. input *pb.ReadRequest
  439. readCount int
  440. wantErr bool
  441. wantResponse []string
  442. }{
  443. {
  444. name: "empty resource name",
  445. readHandler: &TestReadHandler{},
  446. input: &pb.ReadRequest{
  447. ReadLimit: 1,
  448. },
  449. readCount: 1,
  450. wantErr: true,
  451. wantResponse: []string{},
  452. }, {
  453. name: "test ReadLimit=-1",
  454. readHandler: &TestReadHandler{buf: testData},
  455. input: &pb.ReadRequest{
  456. ResourceName: testName,
  457. ReadOffset: 0,
  458. ReadLimit: -1,
  459. },
  460. readCount: 1,
  461. wantErr: true,
  462. }, {
  463. name: "test ReadLimit=1",
  464. readHandler: &TestReadHandler{buf: testData},
  465. input: &pb.ReadRequest{
  466. ResourceName: testName,
  467. ReadOffset: 0,
  468. ReadLimit: 1,
  469. },
  470. readCount: 1,
  471. wantResponse: []string{"0"},
  472. }, {
  473. name: "test ReadLimit=2",
  474. readHandler: &TestReadHandler{buf: testData},
  475. input: &pb.ReadRequest{
  476. ResourceName: testName,
  477. ReadOffset: 0,
  478. ReadLimit: 2,
  479. },
  480. readCount: 1,
  481. wantResponse: []string{"01"},
  482. }, {
  483. name: "test ReadOffset=1 ReadLimit=2",
  484. readHandler: &TestReadHandler{buf: testData},
  485. input: &pb.ReadRequest{
  486. ResourceName: testName,
  487. ReadOffset: 1,
  488. ReadLimit: 2,
  489. },
  490. readCount: 1,
  491. wantResponse: []string{"12"},
  492. }, {
  493. name: "test ReadOffset=2 ReadLimit=2",
  494. readHandler: &TestReadHandler{buf: testData},
  495. input: &pb.ReadRequest{
  496. ResourceName: testName,
  497. ReadOffset: 2,
  498. ReadLimit: 2,
  499. },
  500. readCount: 1,
  501. wantResponse: []string{"23"},
  502. }, {
  503. name: "read all testData at exactly the limit",
  504. readHandler: &TestReadHandler{buf: testData},
  505. input: &pb.ReadRequest{
  506. ResourceName: testName,
  507. ReadOffset: 0,
  508. ReadLimit: int64(len(testData)),
  509. },
  510. readCount: 1,
  511. wantResponse: []string{"0123456789"},
  512. }, {
  513. name: "read all testData",
  514. readHandler: &TestReadHandler{buf: testData},
  515. input: &pb.ReadRequest{
  516. ResourceName: testName,
  517. ReadOffset: 0,
  518. ReadLimit: int64(len(testData)) * 2,
  519. },
  520. readCount: 1,
  521. wantResponse: []string{"0123456789"},
  522. }, {
  523. name: "read all testData 2 times",
  524. readHandler: &TestReadHandler{buf: testData},
  525. input: &pb.ReadRequest{
  526. ResourceName: testName,
  527. ReadOffset: 0,
  528. ReadLimit: int64(len(testData)) * 2,
  529. },
  530. readCount: 2,
  531. wantResponse: []string{"0123456789", "0123456789"},
  532. }, {
  533. name: "test ReadLimit=0",
  534. readHandler: &TestReadHandler{buf: testData},
  535. input: &pb.ReadRequest{
  536. ResourceName: testName,
  537. ReadOffset: 0,
  538. ReadLimit: 0,
  539. },
  540. readCount: 1,
  541. wantResponse: []string{"0123456789"},
  542. }, {
  543. name: "test ReadLimit=1000",
  544. readHandler: &TestReadHandler{buf: testData},
  545. input: &pb.ReadRequest{
  546. ResourceName: testName,
  547. ReadOffset: 0,
  548. ReadLimit: 1000,
  549. },
  550. readCount: 1,
  551. wantResponse: []string{"0123456789"},
  552. }, {
  553. name: "fails with UngettableReadHandler",
  554. readHandler: &UngettableReadHandler{},
  555. input: &pb.ReadRequest{
  556. ResourceName: testName,
  557. ReadOffset: 0,
  558. ReadLimit: int64(len(testData)),
  559. },
  560. readCount: 1,
  561. wantErr: true,
  562. }, {
  563. name: "fails with UnreadableReadHandler",
  564. readHandler: &UnreadableReadHandler{},
  565. input: &pb.ReadRequest{
  566. ResourceName: testName,
  567. ReadOffset: 0,
  568. ReadLimit: int64(len(testData)),
  569. },
  570. readCount: 1,
  571. wantErr: true,
  572. }, {
  573. name: "fails with UnclosableReadHandler",
  574. readHandler: &UnclosableReadHandler{buf: testData},
  575. input: &pb.ReadRequest{
  576. ResourceName: testName,
  577. ReadOffset: 0,
  578. ReadLimit: int64(len(testData)) * 2,
  579. },
  580. readCount: 1,
  581. wantErr: true,
  582. wantResponse: []string{"0123456789"},
  583. }, {
  584. name: "fails with nil ReadRequest",
  585. readHandler: &TestReadHandler{buf: testData},
  586. readCount: 1,
  587. wantErr: true,
  588. }, {
  589. name: "fails with nil ReadHandler",
  590. readHandler: nil,
  591. readCount: 1,
  592. wantErr: true,
  593. },
  594. }
  595. ctx := context.Background()
  596. for _, tc := range testCases {
  597. var writeHandler WriteHandler
  598. if tc.readHandler == nil {
  599. writeHandler = &TestWriteHandler{}
  600. }
  601. setupServer(tc.readHandler, writeHandler)
  602. var responseCount int
  603. var err error
  604. for i := 0; i < tc.readCount; i++ {
  605. err = server.rpc.Read(tc.input, &fakeReadServerImpl{
  606. ctx: ctx,
  607. sender: func(response *pb.ReadResponse) error {
  608. if responseCount >= len(tc.wantResponse) {
  609. t.Fatalf("%s: got %d call(s) to Send(), want %d", tc.name, responseCount+1, len(tc.wantResponse))
  610. }
  611. if got, want := string(response.Data), tc.wantResponse[responseCount]; got != want {
  612. t.Fatalf("%s: response[%d] got %q, want %q", tc.name, responseCount, got, want)
  613. }
  614. responseCount++
  615. return nil
  616. },
  617. })
  618. gotErr := (err != nil)
  619. if i+1 < tc.readCount {
  620. if gotErr {
  621. t.Errorf("%s: Read got err=%v, wantErr=%t, but on Read[%d/%d]. Error should not happen until last call to Read", tc.name, err, tc.wantErr, i+1, tc.readCount)
  622. break
  623. }
  624. } else if gotErr != tc.wantErr {
  625. t.Errorf("%s: Read got err=%v, wantErr=%t", tc.name, err, tc.wantErr)
  626. break
  627. }
  628. }
  629. if responseCount != len(tc.wantResponse) {
  630. t.Errorf("%s: got %d call(s) to Send, want %d", tc.name, responseCount, len(tc.wantResponse))
  631. }
  632. }
  633. }
  634. func TestServerRead_SendError(t *testing.T) {
  635. setupServer(&TestReadHandler{buf: testData}, nil)
  636. err := server.rpc.Read(&pb.ReadRequest{
  637. ResourceName: testName,
  638. ReadOffset: 0,
  639. ReadLimit: int64(len(testData)) * 2,
  640. }, &fakeReadServerImpl{
  641. ctx: context.Background(),
  642. sender: func(response *pb.ReadResponse) error {
  643. if string(response.Data) != testData {
  644. t.Fatalf("Send: got %v, want %q", response, testData)
  645. }
  646. return errors.New("TestServerRead Send() error")
  647. },
  648. })
  649. if err == nil {
  650. t.Fatal("Read() should have failed, but succeeded")
  651. }
  652. }
  653. type fakeWriteServerImpl struct {
  654. pb.ByteStream_WriteServer
  655. ctx context.Context
  656. receiver func() (*pb.WriteRequest, error)
  657. sender func(*pb.WriteResponse) error
  658. }
  659. func (fake *fakeWriteServerImpl) Context() context.Context {
  660. return fake.ctx
  661. }
  662. func (fake *fakeWriteServerImpl) Recv() (*pb.WriteRequest, error) {
  663. return fake.receiver()
  664. }
  665. func (fake *fakeWriteServerImpl) SendMsg(m interface{}) error {
  666. return fake.sender(m.(*pb.WriteResponse))
  667. }
  668. func (fake *fakeWriteServerImpl) SendAndClose(m *pb.WriteResponse) error {
  669. fake.sender(m)
  670. return nil
  671. }
  672. type fakeReadServerImpl struct {
  673. pb.ByteStream_ReadServer
  674. ctx context.Context
  675. sender func(*pb.ReadResponse) error
  676. }
  677. func (fake *fakeReadServerImpl) Context() context.Context {
  678. return fake.ctx
  679. }
  680. func (fake *fakeReadServerImpl) Send(response *pb.ReadResponse) error {
  681. return fake.sender(response)
  682. }
  683. type TestWriteHandler struct {
  684. buf bytes.Buffer // bytes.Buffer implements io.Writer
  685. name string // This service can handle one name only.
  686. }
  687. func (w *TestWriteHandler) GetWriter(ctx context.Context, name string, initOffset int64) (io.Writer, error) {
  688. if w.name == "" {
  689. w.name = name
  690. } else if w.name != name {
  691. return nil, fmt.Errorf("writer already has name=%q, now a new name=%q confuses me", w.name, name)
  692. }
  693. // initOffset is ignored.
  694. return &w.buf, nil
  695. }
  696. func (w *TestWriteHandler) Close(ctx context.Context, name string) error {
  697. w.name = ""
  698. w.buf.Reset()
  699. return nil
  700. }
  701. type UngettableWriteHandler struct{}
  702. func (w *UngettableWriteHandler) GetWriter(ctx context.Context, name string, initOffset int64) (io.Writer, error) {
  703. return nil, errors.New("UngettableWriteHandler.GetWriter() always fails")
  704. }
  705. func (w *UngettableWriteHandler) Close(ctx context.Context, name string) error {
  706. return nil
  707. }
  708. type UnwritableWriter struct{}
  709. func (w *UnwritableWriter) Write(p []byte) (int, error) {
  710. return 0, errors.New("UnwritableWriter.Write() always fails")
  711. }
  712. type UnwritableWriteHandler struct{}
  713. func (w *UnwritableWriteHandler) GetWriter(ctx context.Context, name string, initOffset int64) (io.Writer, error) {
  714. return &UnwritableWriter{}, nil
  715. }
  716. func (w *UnwritableWriteHandler) Close(ctx context.Context, name string) error {
  717. return nil
  718. }
  719. type UnclosableWriter struct{}
  720. func (w *UnclosableWriter) Write(p []byte) (int, error) {
  721. return len(p), nil
  722. }
  723. type UnclosableWriteHandler struct{}
  724. func (w *UnclosableWriteHandler) GetWriter(ctx context.Context, name string, initOffset int64) (io.Writer, error) {
  725. return &UnclosableWriter{}, nil
  726. }
  727. func (w *UnclosableWriteHandler) Close(ctx context.Context, name string) error {
  728. return errors.New("UnclosableWriteHandler.Close() always fails")
  729. }
  730. type TestReadHandler struct {
  731. buf string
  732. name string // This service can handle one name only.
  733. }
  734. // GetWriter() returns an io.ReaderAt to accept reads from the given name.
  735. func (r *TestReadHandler) GetReader(ctx context.Context, name string) (io.ReaderAt, error) {
  736. if r.name == "" {
  737. r.name = name
  738. } else if r.name != name {
  739. return nil, fmt.Errorf("reader already has name=%q, now a new name=%q confuses me", r.name, name)
  740. }
  741. return bytes.NewReader([]byte(r.buf)), nil
  742. }
  743. // Close does nothing.
  744. func (r *TestReadHandler) Close(ctx context.Context, name string) error {
  745. return nil
  746. }
  747. type UngettableReadHandler struct{}
  748. func (r *UngettableReadHandler) GetReader(ctx context.Context, name string) (io.ReaderAt, error) {
  749. return nil, errors.New("UngettableReadHandler.GetReader() always fails")
  750. }
  751. func (r *UngettableReadHandler) Close(ctx context.Context, name string) error {
  752. return nil
  753. }
  754. type UnreadableReader struct{}
  755. func (r *UnreadableReader) ReadAt(p []byte, offset int64) (int, error) {
  756. return 0, errors.New("UnreadableReader.ReadAt() always fails")
  757. }
  758. type UnreadableReadHandler struct{}
  759. func (r *UnreadableReadHandler) GetReader(ctx context.Context, name string) (io.ReaderAt, error) {
  760. return &UnreadableReader{}, nil
  761. }
  762. func (r *UnreadableReadHandler) Close(ctx context.Context, name string) error {
  763. return nil
  764. }
  765. type UnclosableReadHandler struct {
  766. buf string
  767. }
  768. func (r *UnclosableReadHandler) GetReader(ctx context.Context, name string) (io.ReaderAt, error) {
  769. return bytes.NewReader([]byte(r.buf)), nil
  770. }
  771. func (r *UnclosableReadHandler) Close(ctx context.Context, name string) error {
  772. return fmt.Errorf("UnclosableReader.Close(%s) always fails", name)
  773. }
  774. func registerServer() {
  775. gsrv := grpc.NewServer()
  776. var err error
  777. server, err = NewServer(gsrv, &TestReadHandler{}, &TestWriteHandler{})
  778. if err != nil {
  779. log.Fatalf("NewServer() failed: %v", err)
  780. }
  781. }
  782. func setupServer(readHandler ReadHandler, writeHandler WriteHandler) {
  783. setupServerOnce.Do(registerServer)
  784. server.status = make(map[string]*pb.QueryWriteStatusResponse)
  785. server.readHandler = readHandler
  786. server.writeHandler = writeHandler
  787. }