Skip to content

Commit

Permalink
Merge pull request #1 from status-im/ci
Browse files Browse the repository at this point in the history
Add CI
  • Loading branch information
lchenut authored Mar 8, 2024
2 parents d525da3 + 0d10bdd commit 97cd366
Show file tree
Hide file tree
Showing 10 changed files with 221 additions and 20 deletions.
66 changes: 66 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: CI
on:
push:

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
build:
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
target:
- os: linux
cpu: amd64
- os: linux
cpu: i386
- os: macos
cpu: amd64
- os: windows
cpu: amd64
nim: [1.6.16, devel]
include:
- target:
os: linux
builder: ubuntu-20.04
shell: bash
- target:
os: macos
builder: macos-12
shell: bash
- target:
os: windows
builder: windows-2019
shell: msys2 {0}

defaults:
run:
shell: ${{ matrix.shell }}

name: '${{ matrix.target.os }}-${{ matrix.target.cpu }} (Nim ${{ matrix.nim }})'
runs-on: ${{ matrix.builder }}
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: true

- uses: iffy/install-nim@v3
with:
version: ${{ matrix.nim }}


- name: Install deps
run: |
nimble install -dy
- name: Run tests
run: |
nim --version
nimble --version
nimble test
nim c examples/ping.nim
nim c examples/pong.nim
46 changes: 46 additions & 0 deletions tests/asyncunit.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import unittest2, chronos

export unittest2, chronos

template asyncTeardown*(body: untyped): untyped =
teardown:
waitFor((
proc() {.async, gcsafe.} =
body
)())

template asyncSetup*(body: untyped): untyped =
setup:
waitFor((
proc() {.async, gcsafe.} =
body
)())

template asyncTest*(name: string, body: untyped): untyped =
test name:
waitFor((
proc() {.async, gcsafe.} =
body
)())

template flakyAsyncTest*(name: string, attempts: int, body: untyped): untyped =
test name:
var attemptNumber = 0
while attemptNumber < attempts:
let isLastAttempt = attemptNumber == attempts - 1
inc attemptNumber
try:
waitFor((
proc() {.async, gcsafe.} =
body
)())
except Exception as e:
if isLastAttempt: raise e
else: testStatusIMPL = TestStatus.FAILED
finally:
if not isLastAttempt:
if testStatusIMPL == TestStatus.FAILED:
# Retry
testStatusIMPL = TestStatus.OK
else:
break
48 changes: 48 additions & 0 deletions tests/helpers.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
when (NimMajor, NimMinor) < (1, 4):
{.push raises: [Defect].}
else:
{.push raises: [].}

import chronos
import unittest2
export unittest2

const
StreamTransportTrackerName = "stream.transport"
StreamServerTrackerName = "stream.server"
DgramTransportTrackerName = "datagram.transport"

trackerNames = [
StreamTransportTrackerName,
StreamServerTrackerName,
DgramTransportTrackerName,
]

template asyncTest*(name: string, body: untyped): untyped =
test name:
waitFor((proc () {.async, gcsafe.} = body)())

iterator testTrackers*(extras: openArray[string] = []): TrackerBase =
for name in trackerNames:
let t = getTracker(name)
if not isNil(t): yield t
for name in extras:
let t = getTracker(name)
if not isNil(t): yield t

template checkTracker*(name: string) =
var tracker = getTracker(name)
if tracker.isLeaked():
checkpoint tracker.dump()
fail()

template checkTrackers*() =
for tracker in testTrackers():
if tracker.isLeaked():
checkpoint tracker.dump()
fail()
# Also test the GC is not fooling with us
try:
GC_fullCollect()
except:
discard
4 changes: 4 additions & 0 deletions tests/runalltests.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{.used.}

import testdatachannel
import teststun
32 changes: 27 additions & 5 deletions tests/teststun.nim
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
import ../webrtc/stun
import options
import ../webrtc/stun/stun
import ../webrtc/stun/stun_attributes
import ./asyncunit
import binary_serialization

suite "Stun suite":
test "Stun encoding/decoding with padding":
suite "Stun message encoding/decoding":
test "Stun decoding":
let msg = @[ 0x00'u8, 0x01, 0x00, 0xa4, 0x21, 0x12, 0xa4, 0x42, 0x75, 0x6a, 0x58, 0x46, 0x42, 0x58, 0x4e, 0x72, 0x6a, 0x50, 0x4d, 0x2b, 0x00, 0x06, 0x00, 0x63, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2b, 0x77, 0x65, 0x62, 0x72, 0x74, 0x63, 0x2b, 0x76, 0x31, 0x2f, 0x62, 0x71, 0x36, 0x67, 0x69, 0x43, 0x75, 0x4a, 0x38, 0x6e, 0x78, 0x59, 0x46, 0x4a, 0x36, 0x43, 0x63, 0x67, 0x45, 0x59, 0x58, 0x58, 0x2f, 0x78, 0x51, 0x58, 0x56, 0x4c, 0x74, 0x39, 0x71, 0x7a, 0x3a, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2b, 0x77, 0x65, 0x62, 0x72, 0x74, 0x63, 0x2b, 0x76, 0x31, 0x2f, 0x62, 0x71, 0x36, 0x67, 0x69, 0x43, 0x75, 0x4a, 0x38, 0x6e, 0x78, 0x59, 0x46, 0x4a, 0x36, 0x43, 0x63, 0x67, 0x45, 0x59, 0x58, 0x58, 0x2f, 0x78, 0x51, 0x58, 0x56, 0x4c, 0x74, 0x39, 0x71, 0x7a, 0x00, 0xc0, 0x57, 0x00, 0x04, 0x00, 0x00, 0x03, 0xe7, 0x80, 0x2a, 0x00, 0x08, 0x86, 0x63, 0xfd, 0x45, 0xa9, 0xe5, 0x4c, 0xdb, 0x00, 0x24, 0x00, 0x04, 0x6e, 0x00, 0x1e, 0xff, 0x00, 0x08, 0x00, 0x14, 0x16, 0xff, 0x70, 0x8d, 0x97, 0x0b, 0xd6, 0xa3, 0x5b, 0xac, 0x8f, 0x4c, 0x85, 0xe6, 0xa6, 0xac, 0xaa, 0x7a, 0x68, 0x27, 0x80, 0x28, 0x00, 0x04, 0x79, 0x5e, 0x03, 0xd8 ]
check msg == encode(StunMessage.decode(msg))
let stunmsg = StunMessage.decode(msg)
check:
stunmsg.msgType == 1
stunmsg.transactionId.len() == 12
stunmsg.attributes.len() == 6
stunmsg.attributes[0].attributeType == 6 # AttrUsername
stunmsg.attributes[^1].attributeType == 0x8028 # AttrFingerprint

test "Stun encoding":
let transactionId: array[12, byte] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
var msg = StunMessage(msgType: 0x0001'u16, transactionId: transactionId)
msg.attributes.add(ErrorCode.encode(ECUnknownAttribute))
let encoded = msg.encode()
let decoded = StunMessage.decode(encoded)
# cannot do `check msg == decoded` because encode add a Fingerprint
# attribute at the end
check:
decoded.msgType == 1
decoded.transactionId == transactionId
decoded.attributes.len() == 2
decoded.attributes[0].attributeType == 9 # AttrErrorCode
decoded.attributes[^1].attributeType == 0x8028 # AttrFingerprint

test "Error while decoding":
let msgLengthFailed = @[ 0x00'u8, 0x01, 0x00, 0xa4, 0x21, 0x12, 0xa4, 0x42, 0x75, 0x6a, 0x58, 0x46, 0x42, 0x58, 0x4e, 0x72, 0x6a, 0x50, 0x4d ]
Expand Down
25 changes: 23 additions & 2 deletions webrtc.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,32 @@ description = "Webrtc stack"
license = "MIT"
installDirs = @["usrsctp", "webrtc"]

requires "nim >= 1.2.0",
requires "nim >= 1.6.0",
"chronicles >= 0.10.2",
"chronos >= 3.0.6",
"https://github.com/status-im/nim-binary-serialization.git",
"https://github.com/status-im/nim-mbedtls.git"

let nimc = getEnv("NIMC", "nim") # Which nim compiler to use
let lang = getEnv("NIMLANG", "c") # Which backend (c/cpp/js)
let flags = getEnv("NIMFLAGS", "") # Extra flags for the compiler
let verbose = getEnv("V", "") notin ["", "0"]

let cfg =
" --styleCheck:usages --styleCheck:error" &
(if verbose: "" else: " --verbosity:0 --hints:off") &
" --skipParentCfg --skipUserCfg -f" &
" --threads:on --opt:speed"

import hashes

proc runTest(filename: string) =
discard
var excstr = nimc & " " & lang & " -d:debug " & cfg & " " & flags
excstr.add(" -d:nimOldCaseObjects") # TODO: fix this in binary-serialization
if getEnv("CICOV").len > 0:
excstr &= " --nimcache:nimcache/" & filename & "-" & $excstr.hash
exec excstr & " -r " & " tests/" & filename
rmFile "tests/" & filename.toExe

task test, "Run test":
runTest("runalltests")
8 changes: 2 additions & 6 deletions webrtc/dtls/dtls.nim
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,7 @@ proc removeConnection(self: Dtls, conn: DtlsConn, raddr: TransportAddress) {.asy
self.connections.del(raddr)

proc accept*(self: Dtls): Future[DtlsConn] {.async.} =
var
selfvar = self
res = DtlsConn()
var res = DtlsConn()

res.init(self.conn, self.laddr)
mb_ssl_init(res.ssl)
Expand Down Expand Up @@ -334,9 +332,7 @@ proc accept*(self: Dtls): Future[DtlsConn] {.async.} =
return res

proc connect*(self: Dtls, raddr: TransportAddress): Future[DtlsConn] {.async.} =
var
selfvar = self
res = DtlsConn()
var res = DtlsConn()

res.init(self.conn, self.laddr)
mb_ssl_init(res.ssl)
Expand Down
2 changes: 1 addition & 1 deletion webrtc/sctp.nim
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ proc write*(self: SctpConn, buf: seq[byte],
self.sctpSocket.usrsctp_sendv(cast[pointer](addr cpy[0]), cpy.len().uint, nil, 0,
nil, 0, SCTP_SENDV_NOINFO.cuint, 0)
else:
let sendInfo = sctp_sndinfo(
var sendInfo = sctp_sndinfo(
snd_sid: sendParams.streamId,
# TODO: swapBytes => htonl?
snd_ppid: sendParams.protocolId.swapBytes(),
Expand Down
9 changes: 4 additions & 5 deletions webrtc/stun/stun.nim
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,9 @@ type

RawStunMessage = object
msgType: uint16
# it.conten.len() + 8 Because the Fingerprint is added after the encoding
length* {.bin_value: it.content.len().}: uint16
magicCookie: uint32
transactionId: array[12, byte]
transactionId: array[12, byte] # Down from 16 to 12 bytes in RFC5389
content* {.bin_len: it.length.}: seq[byte]

StunMessage* = object
Expand Down Expand Up @@ -98,11 +97,11 @@ proc decode*(T: typedesc[StunMessage], msg: seq[byte]): StunMessage =
transactionId: smi.transactionId,
attributes: RawStunAttribute.decode(smi.content))

proc encode*(msg: StunMessage, userOpt: Option[seq[byte]]): seq[byte] =
proc encode*(msg: StunMessage, userOpt: Option[seq[byte]] = none(seq[byte])): seq[byte] =
const pad = @[0, 3, 2, 1]
var smi = RawStunMessage(msgType: msg.msgType,
magicCookie: magicCookie,
transactionId: msg.transactionId)
magicCookie: magicCookie,
transactionId: msg.transactionId)
for attr in msg.attributes:
smi.content.add(Binary.encode(attr))
smi.content.add(newSeq[byte](pad[smi.content.len() mod 4]))
Expand Down
1 change: 0 additions & 1 deletion webrtc/udp_connection.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
# This file may not be copied, modified, or distributed except according to
# those terms.

import sequtils
import chronos, chronicles

logScope:
Expand Down

0 comments on commit 97cd366

Please sign in to comment.