• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pact-foundation / pact-go / 9770994758

03 Jul 2024 02:37AM UTC coverage: 29.376% (+0.2%) from 29.134%
9770994758

Pull #430

github

YOU54F
chore: rename boolToCInt to CUchar
Pull Request #430: chore(ci): test MacOS & Docker images in CI

29 of 60 new or added lines in 9 files covered. (48.33%)

1 existing line in 1 file now uncovered.

1873 of 6376 relevant lines covered (29.38%)

12.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

71.68
/internal/native/message_server.go
1
package native
2

3
/*
4
#include "pact.h"
5
*/
6
import "C"
7

8
import (
9
        "encoding/json"
10
        "errors"
11
        "fmt"
12
        "log"
13
        "unsafe"
14
)
15

16
type MessagePact struct {
17
        handle C.PactHandle
18
}
19

20
type messageType int
21

22
const (
23
        MESSAGE_TYPE_ASYNC messageType = iota
24
        MESSAGE_TYPE_SYNC
25
)
26

27
type Message struct {
28
        handle      C.InteractionHandle
29
        messageType messageType
30
        pact        *MessagePact
31
        index       int
32
        server      *MessageServer
33
}
34

35
// MessageServer is the public interface for managing the message based interface
36
type MessageServer struct {
37
        messagePact *MessagePact
38
        messages    []*Message
39
}
40

41
// NewMessage initialises a new message for the current contract
42
func NewMessageServer(consumer string, provider string) *MessageServer {
99✔
43
        cConsumer := C.CString(consumer)
99✔
44
        cProvider := C.CString(provider)
99✔
45
        defer free(cConsumer)
99✔
46
        defer free(cProvider)
99✔
47

99✔
48
        return &MessageServer{messagePact: &MessagePact{handle: C.pactffi_new_message_pact(cConsumer, cProvider)}}
99✔
49
}
99✔
50

51
// Sets the additional metadata on the Pact file. Common uses are to add the client library details such as the name and version
52
func (m *MessageServer) WithMetadata(namespace, k, v string) *MessageServer {
9✔
53
        cNamespace := C.CString(namespace)
9✔
54
        defer free(cNamespace)
9✔
55
        cName := C.CString(k)
9✔
56
        defer free(cName)
9✔
57
        cValue := C.CString(v)
9✔
58
        defer free(cValue)
9✔
59

9✔
60
        C.pactffi_with_message_pact_metadata(m.messagePact.handle, cNamespace, cName, cValue)
9✔
61

9✔
62
        return m
9✔
63
}
9✔
64

65
// NewMessage initialises a new message for the current contract
66
// Deprecated: use NewAsyncMessageInteraction instead
67
func (m *MessageServer) NewMessage() *Message {
36✔
68
        // Alias
36✔
69
        return m.NewAsyncMessageInteraction("")
36✔
70
}
36✔
71

72
// NewSyncMessageInteraction initialises a new synchronous message interaction for the current contract
73
func (m *MessageServer) NewSyncMessageInteraction(description string) *Message {
54✔
74
        cDescription := C.CString(description)
54✔
75
        defer free(cDescription)
54✔
76

54✔
77
        i := &Message{
54✔
78
                handle:      C.pactffi_new_sync_message_interaction(m.messagePact.handle, cDescription),
54✔
79
                messageType: MESSAGE_TYPE_SYNC,
54✔
80
                pact:        m.messagePact,
54✔
81
                index:       len(m.messages),
54✔
82
                server:      m,
54✔
83
        }
54✔
84
        m.messages = append(m.messages, i)
54✔
85

54✔
86
        return i
54✔
87
}
54✔
88

89
// NewAsyncMessageInteraction initialises a new asynchronous message interaction for the current contract
90
func (m *MessageServer) NewAsyncMessageInteraction(description string) *Message {
45✔
91
        cDescription := C.CString(description)
45✔
92
        defer free(cDescription)
45✔
93

45✔
94
        i := &Message{
45✔
95
                handle:      C.pactffi_new_message_interaction(m.messagePact.handle, cDescription),
45✔
96
                messageType: MESSAGE_TYPE_ASYNC,
45✔
97
                pact:        m.messagePact,
45✔
98
                index:       len(m.messages),
45✔
99
                server:      m,
45✔
100
        }
45✔
101
        m.messages = append(m.messages, i)
45✔
102

45✔
103
        return i
45✔
104
}
45✔
105

106
func (m *MessageServer) WithSpecificationVersion(version specificationVersion) {
×
107
        C.pactffi_with_specification(m.messagePact.handle, C.int(version))
×
108
}
×
109

110
func (m *Message) Given(state string) *Message {
99✔
111
        cState := C.CString(state)
99✔
112
        defer free(cState)
99✔
113

99✔
114
        C.pactffi_given(m.handle, cState)
99✔
115

99✔
116
        return m
99✔
117
}
99✔
118

119
func (m *Message) GivenWithParameter(state string, params map[string]interface{}) *Message {
54✔
120
        cState := C.CString(state)
54✔
121
        defer free(cState)
54✔
122

54✔
123
        if len(params) == 0 {
54✔
124
                cState := C.CString(state)
×
125
                defer free(cState)
×
126

×
127
                C.pactffi_given(m.handle, cState)
×
128
        } else {
54✔
129
                for k, v := range params {
108✔
130
                        cKey := C.CString(k)
54✔
131
                        defer free(cKey)
54✔
132
                        param := stringFromInterface(v)
54✔
133
                        cValue := C.CString(param)
54✔
134
                        defer free(cValue)
54✔
135

54✔
136
                        C.pactffi_given_with_param(m.handle, cState, cKey, cValue)
54✔
137

54✔
138
                }
54✔
139
        }
140

141
        return m
54✔
142
}
143

144
func (m *Message) ExpectsToReceive(description string) *Message {
54✔
145
        cDescription := C.CString(description)
54✔
146
        defer free(cDescription)
54✔
147

54✔
148
        C.pactffi_message_expects_to_receive(m.handle, cDescription)
54✔
149

54✔
150
        return m
54✔
151
}
54✔
152

153
func (m *Message) WithMetadata(valueOrMatcher map[string]string) *Message {
54✔
154
        for k, v := range valueOrMatcher {
108✔
155

54✔
156
                cName := C.CString(k)
54✔
157
                defer free(cName)
54✔
158

54✔
159
                // TODO: check if matching rules allowed here
54✔
160
                // value := stringFromInterface(v)
54✔
161
                // fmt.Printf("withheaders, sending: %+v \n\n", value)
54✔
162
                // cValue := C.CString(value)
54✔
163
                cValue := C.CString(v)
54✔
164
                defer free(cValue)
54✔
165

54✔
166
                C.pactffi_message_with_metadata(m.handle, cName, cValue)
54✔
167
        }
54✔
168

169
        return m
54✔
170
}
171

172
func (m *Message) WithRequestBinaryContents(body []byte) *Message {
×
173
        cHeader := C.CString("application/octet-stream")
×
174
        defer free(cHeader)
×
175

×
176
        // TODO: handle response
×
NEW
177
        res := C.pactffi_with_binary_file(m.handle, C.int(INTERACTION_PART_REQUEST), cHeader, (*C.uchar)(unsafe.Pointer(&body[0])), C.ulong(len(body)))
×
178

×
NEW
179
        log.Println("[DEBUG] WithRequestBinaryContents - pactffi_with_binary_file returned", bool(res))
×
180

×
181
        return m
×
182
}
×
183
func (m *Message) WithRequestBinaryContentType(contentType string, body []byte) *Message {
9✔
184
        cHeader := C.CString(contentType)
9✔
185
        defer free(cHeader)
9✔
186

9✔
187
        // TODO: handle response
9✔
188
        res := C.pactffi_with_binary_file(m.handle, C.int(INTERACTION_PART_REQUEST), cHeader, (*C.uchar)(unsafe.Pointer(&body[0])), C.ulong(len(body)))
9✔
189

9✔
190
        log.Println("[DEBUG] WithRequestBinaryContents - pactffi_with_binary_file returned", res)
9✔
191

9✔
192
        return m
9✔
193
}
9✔
194

195
func (m *Message) WithRequestJSONContents(body interface{}) *Message {
18✔
196
        value := stringFromInterface(body)
18✔
197

18✔
198
        log.Println("[DEBUG] message WithJSONContents", value)
18✔
199

18✔
200
        return m.WithContents(INTERACTION_PART_REQUEST, "application/json", []byte(value))
18✔
201
}
18✔
202

203
func (m *Message) WithResponseBinaryContents(body []byte) *Message {
×
204
        cHeader := C.CString("application/octet-stream")
×
205
        defer free(cHeader)
×
206

×
207
        // TODO: handle response
×
NEW
208
        C.pactffi_with_binary_file(m.handle, C.int(INTERACTION_PART_RESPONSE), cHeader, (*C.uchar)(unsafe.Pointer(&body[0])), C.ulong(len(body)))
×
209

×
210
        return m
×
211
}
×
212

213
func (m *Message) WithResponseJSONContents(body interface{}) *Message {
9✔
214
        value := stringFromInterface(body)
9✔
215

9✔
216
        log.Println("[DEBUG] message WithJSONContents", value)
9✔
217

9✔
218
        return m.WithContents(INTERACTION_PART_RESPONSE, "application/json", []byte(value))
9✔
219
}
9✔
220

221
// Note that string values here must be NUL terminated.
222
func (m *Message) WithContents(part interactionPart, contentType string, body []byte) *Message {
36✔
223
        cHeader := C.CString(contentType)
36✔
224
        defer free(cHeader)
36✔
225

36✔
226
        res := C.pactffi_with_body(m.handle, C.int(part), cHeader, (*C.char)(unsafe.Pointer(&body[0])))
36✔
227
        log.Println("[DEBUG] response from pactffi_interaction_contents", (bool(res)))
36✔
228

36✔
229
        return m
36✔
230
}
36✔
231

232
// TODO: migrate plugin code to shared struct/code?
233

234
// NewInteraction initialises a new interaction for the current contract
235
func (m *MessageServer) UsingPlugin(pluginName string, pluginVersion string) error {
45✔
236
        cPluginName := C.CString(pluginName)
45✔
237
        defer free(cPluginName)
45✔
238
        cPluginVersion := C.CString(pluginVersion)
45✔
239
        defer free(cPluginVersion)
45✔
240

45✔
241
        r := C.pactffi_using_plugin(m.messagePact.handle, cPluginName, cPluginVersion)
45✔
242
        InstallSignalHandlers()
45✔
243

45✔
244
        // 1 - A general panic was caught.
45✔
245
        // 2 - Failed to load the plugin.
45✔
246
        // 3 - Pact Handle is not valid.
45✔
247
        res := int(r)
45✔
248
        switch res {
45✔
249
        case 1:
×
250
                return ErrPluginGenericPanic
×
251
        case 2:
×
252
                return ErrPluginFailed
×
253
        case 3:
×
254
                return ErrHandleNotFound
×
255
        default:
45✔
256
                if res != 0 {
45✔
257
                        return fmt.Errorf("an unknown error (code: %v) occurred when adding a plugin for the test. Received error code:", res)
×
258
                }
×
259
        }
260

261
        return nil
45✔
262
}
263

264
// NewInteraction initialises a new interaction for the current contract
265
func (m *Message) WithPluginInteractionContents(part interactionPart, contentType string, contents string) error {
45✔
266
        cContentType := C.CString(contentType)
45✔
267
        defer free(cContentType)
45✔
268
        cContents := C.CString(contents)
45✔
269
        defer free(cContents)
45✔
270

45✔
271
        r := C.pactffi_interaction_contents(m.handle, C.int(part), cContentType, cContents)
45✔
272

45✔
273
        // 1 - A general panic was caught.
45✔
274
        // 2 - The mock server has already been started.
45✔
275
        // 3 - The interaction handle is invalid.
45✔
276
        // 4 - The content type is not valid.
45✔
277
        // 5 - The contents JSON is not valid JSON.
45✔
278
        // 6 - The plugin returned an error.
45✔
279
        res := int(r)
45✔
280
        switch res {
45✔
281
        case 1:
×
282
                return ErrPluginGenericPanic
×
283
        case 2:
×
284
                return ErrPluginMockServerStarted
×
285
        case 3:
×
286
                return ErrPluginInteractionHandleInvalid
×
287
        case 4:
×
288
                return ErrPluginInvalidContentType
×
289
        case 5:
×
290
                return ErrPluginInvalidJson
×
291
        case 6:
×
292
                return ErrPluginSpecificError
×
293
        default:
45✔
294
                if res != 0 {
45✔
295
                        return fmt.Errorf("an unknown error (code: %v) occurred when adding a plugin for the test. Received error code:", res)
×
296
                }
×
297
        }
298

299
        return nil
45✔
300
}
301

302
// GetMessageContents retreives the binary contents of the request for a given message
303
// any matchers are stripped away if given
304
// if the contents is from a plugin, the byte[] representation of the parsed
305
// plugin data is returned, again, with any matchers etc. removed
306
func (m *Message) GetMessageRequestContents() ([]byte, error) {
63✔
307
        log.Println("[DEBUG] GetMessageRequestContents")
63✔
308
        if m.messageType == MESSAGE_TYPE_ASYNC {
108✔
309
                iter := C.pactffi_pact_handle_get_message_iter(m.pact.handle)
45✔
310
                log.Println("[DEBUG] pactffi_pact_handle_get_message_iter")
45✔
311
                if iter == nil {
45✔
312
                        return nil, errors.New("unable to get a message iterator")
×
313
                }
×
314
                log.Println("[DEBUG] pactffi_pact_handle_get_message_iter - OK")
45✔
315

45✔
316
                ///////
45✔
317
                // TODO: some debugging in here to see what's exploding.......
45✔
318
                ///////
45✔
319

45✔
320
                log.Println("[DEBUG] pactffi_pact_handle_get_message_iter - len", len(m.server.messages))
45✔
321

45✔
322
                for i := 0; i < len(m.server.messages); i++ {
90✔
323
                        log.Println("[DEBUG] pactffi_pact_handle_get_message_iter - index", i)
45✔
324
                        message := C.pactffi_pact_message_iter_next(iter)
45✔
325
                        log.Println("[DEBUG] pactffi_pact_message_iter_next - message", message)
45✔
326

45✔
327
                        if i == m.index {
90✔
328
                                log.Println("[DEBUG] pactffi_pact_message_iter_next - index match", message)
45✔
329

45✔
330
                                if message == nil {
45✔
331
                                        return nil, errors.New("retrieved a null message pointer")
×
332
                                }
×
333

334
                                len := C.pactffi_message_get_contents_length(message)
45✔
335
                                log.Println("[DEBUG] pactffi_message_get_contents_length - len", len)
45✔
336
                                if len == 0 {
45✔
337
                                        // You can have empty bodies
×
338
                                        log.Println("[DEBUG] message body is empty")
×
339
                                        return nil, nil
×
340
                                }
×
341
                                data := C.pactffi_message_get_contents_bin(message)
45✔
342
                                log.Println("[DEBUG] pactffi_message_get_contents_bin - data", data)
45✔
343
                                if data == nil {
45✔
344
                                        // You can have empty bodies
×
345
                                        log.Println("[DEBUG] message binary contents are empty")
×
346
                                        return nil, nil
×
347
                                }
×
348
                                ptr := unsafe.Pointer(data)
45✔
349
                                bytes := C.GoBytes(ptr, C.int(len))
45✔
350

45✔
351
                                return bytes, nil
45✔
352
                        }
353
                }
354

355
        } else {
18✔
356
                iter := C.pactffi_pact_handle_get_sync_message_iter(m.pact.handle)
18✔
357
                if iter == nil {
18✔
358
                        return nil, errors.New("unable to get a message iterator")
×
359
                }
×
360

361
                for i := 0; i < len(m.server.messages); i++ {
36✔
362
                        message := C.pactffi_pact_sync_message_iter_next(iter)
18✔
363

18✔
364
                        if i == m.index {
36✔
365
                                if message == nil {
18✔
366
                                        return nil, errors.New("retrieved a null message pointer")
×
367
                                }
×
368

369
                                len := C.pactffi_sync_message_get_request_contents_length(message)
18✔
370
                                if len == 0 {
18✔
371
                                        log.Println("[DEBUG] message body is empty")
×
372
                                        return nil, nil
×
373
                                }
×
374
                                data := C.pactffi_sync_message_get_request_contents_bin(message)
18✔
375
                                if data == nil {
18✔
376
                                        log.Println("[DEBUG] message binary contents are empty")
×
377
                                        return nil, nil
×
378
                                }
×
379
                                ptr := unsafe.Pointer(data)
18✔
380
                                bytes := C.GoBytes(ptr, C.int(len))
18✔
381

18✔
382
                                return bytes, nil
18✔
383
                        }
384
                }
385
        }
386

387
        return nil, errors.New("unable to find the message")
×
388
}
389

390
// GetMessageResponseContents retreives the binary contents of the response for a given message
391
// any matchers are stripped away if given
392
// if the contents is from a plugin, the byte[] representation of the parsed
393
// plugin data is returned, again, with any matchers etc. removed
394
func (m *Message) GetMessageResponseContents() ([][]byte, error) {
36✔
395

36✔
396
        responses := make([][]byte, len(m.server.messages))
36✔
397
        if m.messageType == MESSAGE_TYPE_ASYNC {
36✔
398
                return nil, errors.New("invalid request: asynchronous messages do not have response")
×
399
        }
×
400
        iter := C.pactffi_pact_handle_get_sync_message_iter(m.pact.handle)
36✔
401
        if iter == nil {
36✔
402
                return nil, errors.New("unable to get a message iterator")
×
403
        }
×
404

405
        for i := 0; i < len(m.server.messages); i++ {
72✔
406
                message := C.pactffi_pact_sync_message_iter_next(iter)
36✔
407

36✔
408
                if message == nil {
36✔
409
                        return nil, errors.New("retrieved a null message pointer")
×
410
                }
×
411

412
                // Get Response body
413
                len := C.pactffi_sync_message_get_response_contents_length(message, C.size_t(i))
36✔
414
                if len != 0 {
54✔
415
                        data := C.pactffi_sync_message_get_response_contents_bin(message, C.size_t(i))
18✔
416
                        if data == nil {
18✔
417
                                return nil, errors.New("retrieved an empty pointer to the message contents")
×
418
                        }
×
419
                        ptr := unsafe.Pointer(data)
18✔
420
                        bytes := C.GoBytes(ptr, C.int(len))
18✔
421
                        responses[i] = bytes
18✔
422
                }
423
        }
424

425
        return responses, nil
36✔
426
}
427

428
// StartTransport starts up a mock server on the given address:port for the given transport
429
// https://docs.rs/pact_ffi/latest/pact_ffi/mock_server/fn.pactffi_create_mock_server_for_transport.html
430
func (m *MessageServer) StartTransport(transport string, address string, port int, config map[string][]interface{}) (int, error) {
18✔
431
        if len(m.messages) == 0 {
18✔
432
                return 0, ErrNoInteractions
×
433
        }
×
434

435
        log.Println("[DEBUG] mock server starting on address:", address, port)
18✔
436
        cAddress := C.CString(address)
18✔
437
        defer free(cAddress)
18✔
438

18✔
439
        cTransport := C.CString(transport)
18✔
440
        defer free(cTransport)
18✔
441

18✔
442
        configJson := stringFromInterface(config)
18✔
443
        cConfig := C.CString(configJson)
18✔
444
        defer free(cConfig)
18✔
445

18✔
446
        p := C.pactffi_create_mock_server_for_transport(m.messagePact.handle, cAddress, C.ushort(port), cTransport, cConfig)
18✔
447

18✔
448
        // | Error | Description
18✔
449
        // |-------|-------------
18✔
450
        // | -1           | An invalid handle was received. Handles should be created with pactffi_new_pact
18✔
451
        // | -2           | transport_config is not valid JSON
18✔
452
        // | -3           | The mock server could not be started
18✔
453
        // | -4           | The method panicked
18✔
454
        // | -5           | The address is not valid
18✔
455
        msPort := int(p)
18✔
456
        switch msPort {
18✔
457
        case -1:
×
458
                return 0, ErrInvalidMockServerConfig
×
459
        case -2:
×
460
                return 0, ErrInvalidMockServerConfig
×
461
        case -3:
×
462
                return 0, ErrMockServerUnableToStart
×
463
        case -4:
×
464
                return 0, ErrMockServerPanic
×
465
        case -5:
×
466
                return 0, ErrInvalidAddress
×
467
        default:
18✔
468
                if msPort > 0 {
36✔
469
                        log.Println("[DEBUG] mock server running on port:", msPort)
18✔
470
                        return msPort, nil
18✔
471
                }
18✔
472
                return msPort, fmt.Errorf("an unknown error (code: %v) occurred when starting a mock server for the test", msPort)
×
473
        }
474
}
475

476
// NewInteraction initialises a new interaction for the current contract
477
func (m *MessageServer) CleanupPlugins() {
45✔
478
        C.pactffi_cleanup_plugins(m.messagePact.handle)
45✔
479
}
45✔
480

481
// CleanupMockServer frees the memory from the previous mock server.
482
func (m *MessageServer) CleanupMockServer(port int) bool {
18✔
483
        if len(m.messages) == 0 {
18✔
484
                return true
×
485
        }
×
486
        log.Println("[DEBUG] mock server cleaning up port:", port)
18✔
487
        res := C.pactffi_cleanup_mock_server(C.int(port))
18✔
488

18✔
489
        return bool(res)
18✔
490
}
491

492
// MockServerMismatchedRequests returns a JSON object containing any mismatches from
493
// the last set of interactions.
494
func (m *MessageServer) MockServerMismatchedRequests(port int) []MismatchedRequest {
18✔
495
        log.Println("[DEBUG] mock server determining mismatches:", port)
18✔
496
        var res []MismatchedRequest
18✔
497

18✔
498
        mismatches := C.pactffi_mock_server_mismatches(C.int(port))
18✔
499
        // This method can return a nil pointer, in which case, it
18✔
500
        // should be considered a failure (or at least, an issue)
18✔
501
        // converting it to a string might also do nasty things here!
18✔
502
        if mismatches == nil {
18✔
503
                log.Println("[WARN] received a null pointer from the native interface, returning empty list of mismatches")
×
504
                return []MismatchedRequest{}
×
505
        }
×
506

507
        err := json.Unmarshal([]byte(C.GoString(mismatches)), &res)
18✔
508
        if err != nil {
18✔
509
                log.Println("[ERROR] failed to unmarshal mismatches response, returning empty list of mismatches")
×
510
                return []MismatchedRequest{}
×
511
        }
×
512

513
        return res
18✔
514
}
515

516
// MockServerMismatchedRequests returns a JSON object containing any mismatches from
517
// the last set of interactions.
518
func (m *MessageServer) MockServerMatched(port int) bool {
×
519
        log.Println("[DEBUG] mock server determining mismatches:", port)
×
520

×
521
        res := C.pactffi_mock_server_matched(C.int(port))
×
522

×
523
        // TODO: why this number is so big and not a bool? Type def wrong? Port value wrong?
×
524
        // log.Println("MATCHED RES?")
×
525
        // log.Println(int(res))
×
526

×
NEW
527
        return bool(res)
×
528
}
×
529

530
// WritePactFile writes the Pact to file.
531
func (m *MessageServer) WritePactFile(dir string, overwrite bool) error {
27✔
532
        log.Println("[DEBUG] writing pact file for message pact at dir:", dir)
27✔
533
        cDir := C.CString(dir)
27✔
534
        defer free(cDir)
27✔
535

27✔
536
        overwritePact := false
27✔
537
        if overwrite {
27✔
NEW
538
                overwritePact = true
×
539
        }
×
540

541
        res := int(C.pactffi_write_message_pact_file(m.messagePact.handle, cDir, C.bool(overwritePact)))
27✔
542

27✔
543
        /// | Error | Description |
27✔
544
        /// |-------|-------------|
27✔
545
        /// | 1 | The pact file was not able to be written |
27✔
546
        /// | 2 | The message pact for the given handle was not found |
27✔
547
        switch res {
27✔
548
        case 0:
27✔
549
                return nil
27✔
550
        case 1:
×
551
                return ErrUnableToWritePactFile
×
552
        case 2:
×
553
                return ErrHandleNotFound
×
554
        default:
×
555
                return fmt.Errorf("an unknown error ocurred when writing to pact file")
×
556
        }
557
}
558

559
// WritePactFile writes the Pact to file.
560
func (m *MessageServer) WritePactFileForServer(port int, dir string, overwrite bool) error {
18✔
561
        log.Println("[DEBUG] writing pact file for message pact at dir:", dir)
18✔
562
        cDir := C.CString(dir)
18✔
563
        defer free(cDir)
18✔
564

18✔
565
        overwritePact := false
18✔
566
        if overwrite {
36✔
567
                overwritePact = true
18✔
568
        }
18✔
569

570
        res := int(C.pactffi_write_pact_file(C.int(port), cDir, C.bool(overwritePact)))
18✔
571

18✔
572
        /// | Error | Description |
18✔
573
        /// |-------|-------------|
18✔
574
        /// | 1 | The pact file was not able to be written |
18✔
575
        /// | 2 | The message pact for the given handle was not found |
18✔
576
        switch res {
18✔
577
        case 0:
18✔
578
                return nil
18✔
579
        case 1:
×
580
                return ErrMockServerPanic
×
581
        case 2:
×
582
                return ErrUnableToWritePactFile
×
583
        case 3:
×
584
                return ErrHandleNotFound
×
585
        default:
×
586
                return fmt.Errorf("an unknown error ocurred when writing to pact file")
×
587
        }
588
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc