feat: add more test project

Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>
Xinwei Xiong(cubxxw-openim) 2 years ago
parent 67e6e789ec
commit 0031aeca02
No known key found for this signature in database
GPG Key ID: 1BAD6F395338EFDE

@ -38,6 +38,8 @@ jobs:
[Join slack 🤖](https://join.slack.com/t/openimsdk/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q) to connect and communicate with our developers.
Please leave your information in the [✨ discussions](https://github.com/orgs/OpenIMSDK/discussions/426), we expect anyone to join OpenIM developer community.
issue-message: |
Hello! Thank you for filing an issue.

@ -68,7 +68,9 @@ jobs:
- name: verify format
run: |
sudo make format
continue-on-error: true
- name: verify license
run: |
sudo make verify-copyright
sudo make verify-copyright
continue-on-error: true

@ -1,378 +0,0 @@
# Copyright © 2023 OpenIM. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# -----------------------------------------------------------------
# Infrastructural configurations, please modify based on your setup
# -----------------------------------------------------------------
###################### Zookeeper ######################
# Zookeeper configuration
# It's not recommended to modify the schema
#
# Zookeeper address
# Zookeeper username
# Zookeeper password
zookeeper:
schema: openim
address: [ 127.0.0.1:2181 ]
username:
password:
###################### Mysql ######################
# MySQL configuration
# Currently, only single machine setup is supported
#
# Maximum number of open connections
# Maximum number of idle connections
# Maximum lifetime in seconds a connection can be reused
# Log level: 1=slient, 2=error, 3=warn, 4=info
# Slow query threshold in milliseconds
mysql:
address: [ 127.0.0.1:13306 ]
username: root
password: openIM123
database: openIM_v3
maxOpenConn: 1000
maxIdleConn: 100
maxLifeTime: 60
logLevel: 4
slowThreshold: 500
###################### Mongo ######################
# MongoDB configuration
# If uri is not empty, it will be used directly
#
# MongoDB address for standalone setup, Mongos address for sharded cluster setup
# Default MongoDB database name
# Maximum connection pool size
mongo:
uri:
address: [ 127.0.0.1:37017 ]
database: openIM_v3
username: root
password: openIM123
maxPoolSize: 100
###################### Redis ######################
# Redis configuration
#
# Username is required only for Redis version 6.0+
redis:
address: [ 127.0.0.1:16379 ]
username:
password: openIM123
###################### Kafka ######################
# Kafka configuration
#
# Kafka username
# Kafka password
# It's not recommended to modify this topic name
# Consumer group ID, it's not recommended to modify
kafka:
username:
password:
addr: [ 127.0.0.1:9092 ]
latestMsgToRedis:
topic: "latestMsgToRedis"
offlineMsgToMongo:
topic: "offlineMsgToMongoMysql"
msgToPush:
topic: "msgToPush"
consumerGroupID:
msgToRedis: redis
msgToMongo: mongo
msgToMySql: mysql
msgToPush: push
###################### RPC ######################
# RPC configuration
#
# IP address to register with zookeeper when starting RPC, the IP and corresponding rpcPort should be accessible by api/gateway
# Default listen IP is 0.0.0.0
rpc:
registerIP:
listenIP: 0.0.0.0
###################### API ######################
# API configuration
#
# API service port
# Default listen IP is 0.0.0.0
api:
openImApiPort: [ 10002 ]
listenIP: 0.0.0.0
###################### Gateway ######################
# Object storage configuration
#
# Use minio for object storage
# API URL should be accessible by the app
# It's not recommended to modify the bucket name
# Endpoint should be accessible by the app
# Session token
# Configuration for Tencent COS
# Configuration for Aliyun OSS
# apiURL is the address of the api, the access address of the app, use s3 must be configured
# minio.endpoint can be configured as an intranet address,
# minio.signEndpoint is minio public network address
object:
enable: "minio"
apiURL: "http://127.0.0.1:10002"
minio:
bucket: "openim"
endpoint: "http://127.0.0.1:10005"
accessKeyID: "root"
secretAccessKey: "openIM123"
sessionToken: ""
signEndpoint: "http://127.0.0.1:10005"
cos:
bucketURL: "https://temp-1252357374.cos.ap-chengdu.myqcloud.com"
secretID: ""
secretKey: ""
sessionToken: ""
oss:
endpoint: "https://oss-cn-chengdu.aliyuncs.com"
bucket: "demo-9999999"
bucketURL: "https://demo-9999999.oss-cn-chengdu.aliyuncs.com"
accessKeyID: ""
accessKeySecret: ""
sessionToken: ""
# RPC service ports
# These ports are passed into the program by the script and are not recommended to modify
# For launching multiple programs, just fill in multiple ports separated by commas
# For example, [10110, 10111]
rpcPort:
openImUserPort: [ 10110 ]
openImFriendPort: [ 10120 ]
openImMessagePort: [ 10130 ]
openImMessageGatewayPort: [ 10140 ]
openImGroupPort: [ 10150 ]
openImAuthPort: [ 10160 ]
openImPushPort: [ 10170 ]
openImConversationPort: [ 10180 ]
openImThirdPort: [ 10190 ]
# RPC service names for registration, it's not recommended to modify these
rpcRegisterName:
openImUserName: User
openImFriendName: Friend
openImMsgName: Msg
openImPushName: Push
openImMessageGatewayName: MessageGateway
openImGroupName: Group
openImAuthName: Auth
openImConversationName: Conversation
openImThirdName: Third
# Log configuration
#
# Storage directory
# Log rotation time
# Maximum number of logs to retain
# Log level, 6 means all levels
# Whether to output to stdout
# Whether to output in json format
# Whether to include stack trace in logs
log:
storageLocation: ../../../../../logs/
rotationTime: 24
remainRotationCount: 2
remainLogLevel: 6
isStdout: false
isJson: false
withStack: false
# Long connection server configuration
#
# Websocket port for msg_gateway
# Maximum number of websocket connections
# Maximum length of websocket request package
# Websocket connection handshake timeout
longConnSvr:
openImWsPort: [ 10001 ]
websocketMaxConnNum: 100000
websocketMaxMsgLen: 4096
websocketTimeout: 10
# Push notification service configuration
#
# Use GeTui for push notifications
# GeTui offline push configuration
# FCM offline push configuration
# Account file, place it in the config directory
# JPush configuration, modify these after applying in JPush backend
push:
enable: getui
geTui:
pushUrl: "https://restapi.getui.com/v2/$appId"
masterSecret: ""
appKey: ""
intent: ""
channelID: ""
channelName: ""
fcm:
serviceAccount: "x.json"
jpns:
appKey:
masterSecret:
pushUrl:
pushIntent:
# App manager configuration
#
# Built-in app manager user IDs
# Built-in app manager nicknames
manager:
userID: [ "openIM123456","openIM654321","openIMAdmin" ]
nickname: [ "system1","system2", "system3" ]
# Multi-platform login policy
# For each platform(Android, iOS, Windows, Mac, web), only one can be online at a time
multiLoginPolicy: 1
# Whether to store messages in MySQL, messages in MySQL are only used for management background
chatPersistenceMysql: true
# Message cache timeout in seconds, it's not recommended to modify
msgCacheTimeout: 86400
# Whether to enable read receipts for group chat
groupMessageHasReadReceiptEnable: true
# Whether to enable read receipts for single chat
singleMessageHasReadReceiptEnable: true
# MongoDB offline message retention period in days
retainChatRecords: 365
# Schedule to clear expired messages(older than retainChatRecords days) in MongoDB every Wednesday at 2am
# This deletion is just for cleaning up disk usage according to previous configuration retainChatRecords, no notification will be sent
chatRecordsClearTime: "0 2 * * 3"
# Schedule to auto delete messages every day at 2am
# This deletion is for messages that have been retained for more than msg_destruct_time (seconds) in the conversation field
msgDestructTime: "0 2 * * *"
# Secret key
secret: openIM123
# Token policy
#
# Token expiration period in days
tokenPolicy:
expire: 90
# Message verification policy
#
# Whether to verify friendship when sending messages
messageVerify:
friendVerify: false
# iOS push notification configuration
#
# iOS push notification sound
# Whether to count badge
# Whether it's production environment
iosPush:
pushSound: "xxx"
badgeCount: true
production: false
# Callback configuration
#
# Callback URL
# Whether to enable this callback event
# Timeout in seconds
# Whether to continue execution if callback fails
callback:
url:
beforeSendSingleMsg:
enable: false
timeout: 5
failedContinue: true
afterSendSingleMsg:
enable: false
timeout: 5
beforeSendGroupMsg:
enable: false
timeout: 5
failedContinue: true
afterSendGroupMsg:
enable: false
timeout: 5
msgModify:
enable: false
timeout: 5
failedContinue: true
userOnline:
enable: false
timeout: 5
userOffline:
enable: false
timeout: 5
userKickOff:
enable: false
timeout: 5
offlinePush:
enable: false
timeout: 5
failedContinue: true
onlinePush:
enable: false
timeout: 5
failedContinue: true
superGroupOnlinePush:
enable: false
timeout: 5
failedContinue: true
beforeAddFriend:
enable: false
timeout: 5
failedContinue: true
beforeCreateGroup:
enable: false
timeout: 5
failedContinue: true
beforeMemberJoinGroup:
enable: false
timeout: 5
failedContinue: true
beforeSetGroupMemberInfo:
enable: false
timeout: 5
failedContinue: true
setMessageReactionExtensions:
enable: false
timeout: 5
failedContinue: true
###################### Prometheus ######################
# Prometheus configuration
# The number of Prometheus ports per service needs to correspond to rpcPort
# The number of ports needs to be consistent with msg_transfer_service_num in script/path_info.sh
prometheus:
enable: false
userPrometheusPort: [ 20110 ]
friendPrometheusPort: [ 20120 ]
messagePrometheusPort: [ 20130 ]
messageGatewayPrometheusPort: [ 20140 ]
groupPrometheusPort: [ 20150 ]
authPrometheusPort: [ 20160 ]
pushPrometheusPort: [ 20170 ]
conversationPrometheusPort: [ 20230 ]
rtcPrometheusPort: [ 21300 ]
thirdPrometheusPort: [ 21301 ]
messageTransferPrometheusPort: [ 21400, 21401, 21402, 21403 ]

@ -1,3 +1,17 @@
# Copyright © 2023 OpenIM. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ================= Basic Configuration ===================
# User for authentication or system operations
USER=${USER}
@ -66,3 +80,7 @@ MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY}
# Secret key corresponding to the access key for MinIO authentication
MINIO_SECRET_KEY=${MINIO_SECRET_KEY}
# ================== OpenIM Web ===========================
OPENIM_WEB_DIST_PATH=${OPENIM_WEB_DIST_PATH}
OPENIM_WEB_PPRT=${OPENIM_WEB_PPRT}

@ -94,6 +94,16 @@ services:
restart: always
command: minio server /data --console-address ':9090'
# openim-web:
# image: ghcr.io/openimsdk/openim-web:main
# container_name: openim-web
# environment:
# - OPENIM_WEB_DIST_PATH=${OPENIM_WEB_DIST_PATH}
# - OPENIM_WEB_PPRT=${OPENIM_WEB_PPRT}
# restart: always
# ports:
# - "${OPENIM_WEB_PPRT}:11001"
openim-server:
image: ghcr.io/openimsdk/openim-server:main
# image: registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-server:main

@ -8,5 +8,6 @@ use (
./tools/infra
./tools/ncpu
./tools/versionchecker
./tools/web
./tools/yamlfmt
)

@ -70,6 +70,11 @@ def "OPENIM_LOG_DIR" "/var/log/openim"
def "CA_FILE" "${OPENIM_CONFIG_DIR}/cert/ca.pem"
def "OPNEIM_CONFIG" ""${OPENIM_ROOT}"/config"
# OpenIM Web
def "OPENIM_WEB_DIST_PATH" "/app/dist"
def "OPENIM_WEB_PPRT" "11001"
# TODO 注意: 一般的配置都可以使用 def 函数来定义,如果是包含特殊字符,比如说:
# TODO readonly MSG_DESTRUCT_TIME=${MSG_DESTRUCT_TIME:-'0 2 * * *'}
# TODO 使用 readonly 来定义合适,负责无法正常解析, 并且 yaml 模板需要加 "" 来包裹

@ -0,0 +1,41 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"testing"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/stretchr/testify/assert"
)
func TestCheckMysql(t *testing.T) {
err := mockInitCfg()
assert.NoError(t, err, "Initialization should not produce errors")
err = checkMysql()
if err != nil {
// You might expect an error if MySQL isn't running locally with the mock credentials.
t.Logf("Expected error due to mock configuration: %v", err)
}
}
// Mock for initCfg for testing purpose
func mockInitCfg() error {
config.Config.Mysql.Username = "root"
config.Config.Mysql.Password = "openIM123"
config.Config.Mysql.Address = []string{"127.0.0.1:13306"}
return nil
}

@ -0,0 +1,64 @@
# OpenIM Web Service
- [OpenIM Web Service](#openim-web-service)
- [Overview](#overview)
- [User](#user)
- [Docker Deployment](#docker-deployment)
- [Build the Docker Image](#build-the-docker-image)
- [Run the Docker Container](#run-the-docker-container)
- [Configuration](#configuration)
- [Contributions](#contributions)
OpenIM Web Service is a lightweight containerized service built with Go. The service serves static files and allows customization via environment variables.
## Overview
- Built using Go.
- Deployed as a Docker container.
- Serves static files from a directory which can be set via an environment variable.
- The default port for the service is `20001`, but it can be customized using an environment variable.
## User
example
```bash
# ./web -h
Usage of ./web:
-distPath string
Path to the distribution (default "/app/dist")
-port string
Port to run the server on (default "20001")
```
## Docker Deployment
### Build the Docker Image
Even though we've implemented automation, it's to make the developer experience easier:
To build the Docker image for OpenIM Web Service:
```
docker build -t openim-web .
```
### Run the Docker Container
To run the service:
```
docker run -e DIST_PATH=/app/dist -e PORT=20001 -p 20001:20001 openim-web
```
## Configuration
You can configure the OpenIM Web Service using the following environment variables:
- **DIST_PATH**: The path to the directory containing the static files. Default: `/app/dist`.
- **PORT**: The port on which the service listens. Default: `11001`.
## Contributions
We welcome contributions from the community. If you find any bugs or have feature suggestions, please create an issue or send a pull request.

@ -0,0 +1,5 @@
module github.com/OpenIMSDK/Open-IM-Server/tools/web
go 1.18
require gopkg.in/yaml.v2 v2.4.0

@ -0,0 +1,4 @@
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

@ -0,0 +1,44 @@
package main
import (
"flag"
"log"
"net/http"
"os"
)
var (
distPathFlag string
portFlag string
)
func init() {
flag.StringVar(&distPathFlag, "distPath", "/app/dist", "Path to the distribution")
flag.StringVar(&portFlag, "port", "11001", "Port to run the server on")
}
func main() {
flag.Parse()
distPath := getConfigValue("DIST_PATH", distPathFlag, "/app/dist")
fs := http.FileServer(http.Dir(distPath))
http.Handle("/", fs)
port := getConfigValue("PORT", portFlag, "11001")
log.Printf("Server listening on port %s in %s...", port, distPath)
err := http.ListenAndServe(":"+port, nil)
if err != nil {
log.Fatal(err)
}
}
func getConfigValue(envKey, flagValue, fallback string) string {
envVal := os.Getenv(envKey)
if envVal != "" {
return envVal
}
if flagValue != "" {
return flagValue
}
return fallback
}

@ -0,0 +1,57 @@
package main
import (
"os"
"testing"
)
func TestGetConfigValue(t *testing.T) {
tests := []struct {
name string
envKey string
envValue string
flagValue string
fallback string
wantResult string
}{
{
name: "environment variable set",
envKey: "TEST_KEY",
envValue: "envValue",
flagValue: "",
fallback: "default",
wantResult: "envValue",
},
{
name: "flag set and environment variable not set",
envKey: "TEST_KEY",
envValue: "",
flagValue: "flagValue",
fallback: "default",
wantResult: "flagValue",
},
{
name: "nothing set, use fallback",
envKey: "TEST_KEY",
envValue: "",
flagValue: "",
fallback: "default",
wantResult: "default",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.envValue != "" {
os.Setenv(tt.envKey, tt.envValue)
defer os.Unsetenv(tt.envKey)
}
got := getConfigValue(tt.envKey, tt.flagValue, tt.fallback)
if got != tt.wantResult {
t.Errorf("getConfigValue(%s, %s, %s) = %s; want %s", tt.envKey, tt.flagValue, tt.fallback, got, tt.wantResult)
}
})
}
}
Loading…
Cancel
Save