Skip to content

Commit 91e3576

Browse files
authored
Merge pull request #4 from defanator/ci
Introduce basic CI workflow
2 parents 1e1f71c + 1d5c32e commit 91e3576

File tree

7 files changed

+197
-1
lines changed

7 files changed

+197
-1
lines changed

.github/workflows/ci.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: ci
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
pull_request:
7+
branches:
8+
- main
9+
10+
jobs:
11+
build:
12+
strategy:
13+
fail-fast: false
14+
matrix:
15+
include:
16+
- architecture: amd64
17+
runner_os: ubuntu-24.04
18+
- architecture: arm64
19+
runner_os: ubuntu-24.04-arm
20+
runs-on: ${{ matrix.runner_os }}
21+
name: build-${{ matrix.architecture }}
22+
steps:
23+
- uses: actions/checkout@v4
24+
with:
25+
fetch-depth: 0
26+
- name: Setup Go
27+
uses: actions/setup-go@v5
28+
with:
29+
go-version: '1.24.x'
30+
- name: Show environment
31+
run: make show-env
32+
- name: Build watchmaker
33+
run: make build_native
34+
- name: Build examples
35+
run: make examples
36+
- name: Run tests
37+
run: make test
38+
- name: Save binaries as artifacts
39+
uses: actions/upload-artifact@v4
40+
with:
41+
name: watchmaker-${{ matrix.architecture }}
42+
path: |
43+
bin/watchmaker*
44+
fakeclock/*.o
45+
retention-days: 14

Makefile

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
TOPDIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
44
SELF := $(abspath $(lastword $(MAKEFILE_LIST)))
55

6+
GITHUB_RUN_ID ?= 0
67
GIT_URL := $(shell git remote -v|grep push|awk '{print $$2}')
78
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
89
GIT_COMMIT := $(shell git rev-parse HEAD)
@@ -52,6 +53,7 @@ show-var-%:
5253
SHOW_ENV_VARS = \
5354
TOPDIR \
5455
SELF \
56+
GITHUB_RUN_ID \
5557
GIT_URL \
5658
GIT_BRANCH \
5759
GIT_COMMIT \
@@ -80,7 +82,7 @@ build-env: ## Run building environment in Docker container
8082
docker run -it --rm --network host -v $(shell pwd):/go/src/watchmaker -w /go/src/watchmaker golang:latest /bin/bash
8183

8284
examples: ## Build examples
83-
$(MAKE) -C example
85+
$(MAKE) -C example build
8486

8587
.PHONY: init_env_amd64
8688
init_env_amd64: ## Install dependencies to amd64/x86_64 host
@@ -179,8 +181,17 @@ build_arm64_aarch64: build_arm64_arm64
179181

180182
build_arm64: build_arm64_$(ARCH) ## Build arm64 binaries (auto-detect host arch)
181183

184+
build_x86_64: build_amd64
185+
build_aarch64: build_arm64
186+
build_native: build_$(ARCH)
187+
188+
.PHONY: test
189+
test: ## Run tests
190+
GITHUB_RUN_ID=$(GITHUB_RUN_ID) make -C test test
191+
182192
.PHONY: clean
183193
clean: ## Clean up
184194
rm -f fakeclock/*.o
185195
rm -rf bin
186196
$(MAKE) -C example clean
197+
$(MAKE) -C test clean

test/Makefile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/env make -f
2+
3+
TOPDIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
4+
SELF := $(abspath $(lastword $(MAKEFILE_LIST)))
5+
6+
TESTS_C = test_clock_gettime test_gettimeofday test_time
7+
SOURCES_C = $(addsuffix .c, $(TESTS_C))
8+
9+
build: $(TESTS_C)
10+
11+
$(TESTS_C): $(SOURCES_C)
12+
gcc -o $@ $@.c
13+
14+
run-test-%: $(TESTS_C)
15+
$(TOPDIR)/runtest.sh "$*" "$(TOPDIR)"
16+
17+
test: run-test-clock_gettime run-test-gettimeofday run-test-time
18+
19+
.PHONY: clean
20+
clean:
21+
rm -f $(TESTS_C)

test/runtest.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/bin/sh -eux
2+
3+
if [ "${GITHUB_RUN_ID}" -gt 0 ]; then
4+
_SUDO="sudo"
5+
else
6+
_SUDO=
7+
fi
8+
9+
TESTPROC="$1"
10+
TESTROOT="$2"
11+
OUTPUT=$(mktemp "/tmp/test-${TESTPROC}.XXXXXX")
12+
13+
cleanup() {
14+
rm -f "${OUTPUT}"
15+
}
16+
17+
trap "cleanup" EXIT
18+
19+
_GOARCH=$(go env GOARCH)
20+
21+
if [ ! -x "${TESTROOT}/test_${TESTPROC}" ]; then
22+
echo "${TESTROOT}/test_${TESTPROC} not found" >&2
23+
exit 1
24+
fi
25+
26+
"${TESTROOT}/test_${TESTPROC}" >"${OUTPUT}" 2>&1 &
27+
28+
pid=$!
29+
30+
sleep 1
31+
32+
${_SUDO} "${TESTROOT}/../bin/watchmaker_linux_${_GOARCH}" --faketime '2021-01-01' --pid "$pid"
33+
34+
wait
35+
36+
cat "${OUTPUT}"
37+
38+
grep -l -- "2021" "${OUTPUT}"

test/test_clock_gettime.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <stdio.h>
2+
#include <unistd.h>
3+
#include <time.h>
4+
5+
int main() {
6+
struct timespec ts_realtime;
7+
struct tm *tm_info;
8+
char buffer[26];
9+
10+
for (int i = 0; i < 10; i++) {
11+
if (clock_gettime(CLOCK_REALTIME, &ts_realtime) == -1) {
12+
perror("clock_gettime(CLOCK_REALTIME) failed");
13+
return 1;
14+
}
15+
16+
tm_info = localtime(&ts_realtime.tv_sec);
17+
if (tm_info == NULL) {
18+
perror("localtime() failed");
19+
return 1;
20+
}
21+
22+
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm_info);
23+
printf("[%d] clock_gettime(CLOCK_REALTIME) returns: %s.%09ld\n", getpid(), buffer, ts_realtime.tv_nsec);
24+
25+
sleep(1);
26+
}
27+
28+
return 0;
29+
}

test/test_gettimeofday.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <sys/time.h>
2+
#include <stdio.h>
3+
#include <unistd.h>
4+
#include <time.h>
5+
6+
int main() {
7+
struct timeval tv;
8+
struct tm *tm_info;
9+
char buffer[26];
10+
11+
for (int i = 0; i < 10; i++) {
12+
if (gettimeofday(&tv, NULL) == -1) {
13+
perror("gettimeofday() failed");
14+
return 1;
15+
}
16+
17+
tm_info = localtime(&tv.tv_sec);
18+
19+
if (tm_info == NULL) {
20+
perror("localtime() failed");
21+
return 1;
22+
}
23+
24+
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm_info);
25+
26+
printf("[%d] gettimeofday() returns: %s.%06ld\n", getpid(), buffer, tv.tv_usec);
27+
sleep(1);
28+
}
29+
30+
return 0;
31+
}

test/test_time.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <stdio.h>
2+
#include <unistd.h>
3+
#include <time.h>
4+
5+
int main() {
6+
time_t current_time;
7+
8+
for (int i = 0; i < 10; i++) {
9+
current_time = time(NULL);
10+
if (current_time == -1) {
11+
perror("time() failed");
12+
return 1;
13+
}
14+
15+
printf("[%d] time() returns: %s", getpid(), ctime(&current_time));
16+
17+
sleep(1);
18+
}
19+
20+
return 0;
21+
}

0 commit comments

Comments
 (0)