1570af302Sopenharmony_ci/**
2570af302Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3570af302Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4570af302Sopenharmony_ci * you may not use this file except in compliance with the License.
5570af302Sopenharmony_ci * You may obtain a copy of the License at
6570af302Sopenharmony_ci *
7570af302Sopenharmony_ci *   http://www.apache.org/licenses/LICENSE-2.0
8570af302Sopenharmony_ci *
9570af302Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10570af302Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11570af302Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12570af302Sopenharmony_ci * See the License for the specific language governing permissions and
13570af302Sopenharmony_ci * limitations under the License.
14570af302Sopenharmony_ci */
15570af302Sopenharmony_ci
16570af302Sopenharmony_ci#include <arpa/inet.h>
17570af302Sopenharmony_ci#include <ctype.h>
18570af302Sopenharmony_ci#include <netinet/in.h>
19570af302Sopenharmony_ci#include <pthread.h>
20570af302Sopenharmony_ci#include <stdio.h>
21570af302Sopenharmony_ci#include <sys/socket.h>
22570af302Sopenharmony_ci#include <string.h>
23570af302Sopenharmony_ci#include <stdlib.h>
24570af302Sopenharmony_ci#include "functionalext.h"
25570af302Sopenharmony_ci
26570af302Sopenharmony_citypedef void (*TEST_FUN)();
27570af302Sopenharmony_ci#define BUF_SIZE (100)
28570af302Sopenharmony_ci#define PORT 2288
29570af302Sopenharmony_ci#define WAIT() pthread_barrier_wait(&g_barrier)
30570af302Sopenharmony_cistatic const char *g_cliMsg = "Hello, this is client";
31570af302Sopenharmony_cistatic const char *g_localHost = "127.0.0.1";
32570af302Sopenharmony_cistatic pthread_barrier_t g_barrier;
33570af302Sopenharmony_ci
34570af302Sopenharmony_civoid *SampleServerTask()
35570af302Sopenharmony_ci{
36570af302Sopenharmony_ci    int *ret = (int *)malloc(sizeof(int));
37570af302Sopenharmony_ci    int rets = -1;
38570af302Sopenharmony_ci    int sListen = socket(AF_INET, SOCK_STREAM, 0);
39570af302Sopenharmony_ci    if (sListen == -1) {
40570af302Sopenharmony_ci        *ret = -1;
41570af302Sopenharmony_ci        return ret;
42570af302Sopenharmony_ci    }
43570af302Sopenharmony_ci    int flag = 1;
44570af302Sopenharmony_ci    rets = setsockopt(sListen, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));
45570af302Sopenharmony_ci    struct sockaddr_in srvAddr = {0};
46570af302Sopenharmony_ci    srvAddr.sin_family = AF_INET;
47570af302Sopenharmony_ci    srvAddr.sin_addr.s_addr = inet_addr(g_localHost);
48570af302Sopenharmony_ci    srvAddr.sin_port = htons(PORT);
49570af302Sopenharmony_ci    rets = bind(sListen, (struct sockaddr *)&srvAddr, sizeof(srvAddr));
50570af302Sopenharmony_ci    if (rets != 0) {
51570af302Sopenharmony_ci        close(sListen);
52570af302Sopenharmony_ci        *ret = -1;
53570af302Sopenharmony_ci        return ret;
54570af302Sopenharmony_ci    }
55570af302Sopenharmony_ci    rets = listen(sListen, 2);
56570af302Sopenharmony_ci    if (rets != 0) {
57570af302Sopenharmony_ci        close(sListen);
58570af302Sopenharmony_ci        *ret = -1;
59570af302Sopenharmony_ci        return ret;
60570af302Sopenharmony_ci    }
61570af302Sopenharmony_ci    WAIT();
62570af302Sopenharmony_ci    struct sockaddr_in clnAddr = {0};
63570af302Sopenharmony_ci    socklen_t clnAddrLen = sizeof(clnAddr);
64570af302Sopenharmony_ci    int sClient = accept(sListen, (struct sockaddr *)&clnAddr, &clnAddrLen);
65570af302Sopenharmony_ci    static char buf[BUF_SIZE + 1] = {0};
66570af302Sopenharmony_ci    memset(buf, '\0', BUF_SIZE);
67570af302Sopenharmony_ci    rets = recv(sClient, buf, sizeof(buf), 0);
68570af302Sopenharmony_ci    close(sClient);
69570af302Sopenharmony_ci    close(sListen);
70570af302Sopenharmony_ci    return ret;
71570af302Sopenharmony_ci}
72570af302Sopenharmony_ci
73570af302Sopenharmony_civoid *SampleClientTask()
74570af302Sopenharmony_ci{
75570af302Sopenharmony_ci    int clnFd = socket(AF_INET, SOCK_STREAM, 0);
76570af302Sopenharmony_ci    WAIT();
77570af302Sopenharmony_ci    struct sockaddr_in srvAddr = {0};
78570af302Sopenharmony_ci    srvAddr.sin_family = AF_INET;
79570af302Sopenharmony_ci    srvAddr.sin_addr.s_addr = inet_addr(g_localHost);
80570af302Sopenharmony_ci    srvAddr.sin_port = htons(PORT);
81570af302Sopenharmony_ci    int ret = connect(clnFd, (struct sockaddr *)&srvAddr, sizeof(srvAddr));
82570af302Sopenharmony_ci    EXPECT_EQ("send_0100", 0, ret);
83570af302Sopenharmony_ci    static char buf[BUF_SIZE + 1] = {0};
84570af302Sopenharmony_ci    memset(buf, '\0', BUF_SIZE);
85570af302Sopenharmony_ci    strcpy(buf, g_cliMsg);
86570af302Sopenharmony_ci    int sendRet = send(clnFd, buf, sizeof(buf), 0);
87570af302Sopenharmony_ci    EXPECT_EQ("send_0100", sendRet, sizeof(buf));
88570af302Sopenharmony_ci    close(clnFd);
89570af302Sopenharmony_ci    return NULL;
90570af302Sopenharmony_ci}
91570af302Sopenharmony_ci
92570af302Sopenharmony_civoid *SampleServerNullTask()
93570af302Sopenharmony_ci{
94570af302Sopenharmony_ci    int *ret = (int *)malloc(sizeof(int));
95570af302Sopenharmony_ci    int rets = 0;
96570af302Sopenharmony_ci    int sListen = socket(AF_INET, SOCK_STREAM, 0);
97570af302Sopenharmony_ci    if (sListen == -1) {
98570af302Sopenharmony_ci        *ret = -1;
99570af302Sopenharmony_ci        return ret;
100570af302Sopenharmony_ci    }
101570af302Sopenharmony_ci    int flag = 1;
102570af302Sopenharmony_ci    rets = setsockopt(sListen, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));
103570af302Sopenharmony_ci    struct sockaddr_in srvAddr = {0};
104570af302Sopenharmony_ci    srvAddr.sin_family = AF_INET;
105570af302Sopenharmony_ci    srvAddr.sin_addr.s_addr = inet_addr(g_localHost);
106570af302Sopenharmony_ci    srvAddr.sin_port = htons(PORT);
107570af302Sopenharmony_ci    rets = bind(sListen, (struct sockaddr *)&srvAddr, sizeof(srvAddr));
108570af302Sopenharmony_ci    if (rets != 0) {
109570af302Sopenharmony_ci        close(sListen);
110570af302Sopenharmony_ci        *ret = -1;
111570af302Sopenharmony_ci        return ret;
112570af302Sopenharmony_ci    }
113570af302Sopenharmony_ci    rets = listen(sListen, 2);
114570af302Sopenharmony_ci    if (rets != 0) {
115570af302Sopenharmony_ci        close(sListen);
116570af302Sopenharmony_ci        *ret = -1;
117570af302Sopenharmony_ci        return ret;
118570af302Sopenharmony_ci    }
119570af302Sopenharmony_ci    WAIT();
120570af302Sopenharmony_ci    struct sockaddr_in clnAddr = {0};
121570af302Sopenharmony_ci    socklen_t clnAddrLen = sizeof(clnAddr);
122570af302Sopenharmony_ci    accept(sListen, (struct sockaddr *)&clnAddr, &clnAddrLen);
123570af302Sopenharmony_ci    close(sListen);
124570af302Sopenharmony_ci    return ret;
125570af302Sopenharmony_ci}
126570af302Sopenharmony_ci
127570af302Sopenharmony_civoid *SampleClientNullTask()
128570af302Sopenharmony_ci{
129570af302Sopenharmony_ci    int clnFd = socket(AF_INET, SOCK_STREAM, 0);
130570af302Sopenharmony_ci    WAIT();
131570af302Sopenharmony_ci    struct sockaddr_in srvAddr = {0};
132570af302Sopenharmony_ci    srvAddr.sin_family = AF_INET;
133570af302Sopenharmony_ci    srvAddr.sin_addr.s_addr = inet_addr(g_localHost);
134570af302Sopenharmony_ci    srvAddr.sin_port = htons(PORT);
135570af302Sopenharmony_ci    int ret = connect(clnFd, (struct sockaddr *)&srvAddr, sizeof(srvAddr));
136570af302Sopenharmony_ci    EXPECT_EQ("send_0200", 0, ret);
137570af302Sopenharmony_ci    static char buf[BUF_SIZE + 1] = {0};
138570af302Sopenharmony_ci    memset(buf, '\0', BUF_SIZE);
139570af302Sopenharmony_ci    strcpy(buf, g_cliMsg);
140570af302Sopenharmony_ci    int result = send(clnFd, NULL, sizeof(buf), 0);
141570af302Sopenharmony_ci    EXPECT_EQ("send_0200", result, -1);
142570af302Sopenharmony_ci    return NULL;
143570af302Sopenharmony_ci}
144570af302Sopenharmony_ci
145570af302Sopenharmony_ci/*
146570af302Sopenharmony_ci * @tc.name      : send_0100
147570af302Sopenharmony_ci * @tc.desc      : Verify that the client sent successfully
148570af302Sopenharmony_ci * @tc.level     : Level 0
149570af302Sopenharmony_ci */
150570af302Sopenharmony_civoid send_0100(void)
151570af302Sopenharmony_ci{
152570af302Sopenharmony_ci    pthread_t srv;
153570af302Sopenharmony_ci    pthread_t cli;
154570af302Sopenharmony_ci    int ret = pthread_barrier_init(&g_barrier, 0, 2);
155570af302Sopenharmony_ci    EXPECT_EQ("send_0100", 0, ret);
156570af302Sopenharmony_ci    ret = pthread_create(&srv, NULL, SampleServerTask, NULL);
157570af302Sopenharmony_ci    EXPECT_EQ("send_0100", 0, ret);
158570af302Sopenharmony_ci    ret = pthread_create(&cli, NULL, SampleClientTask, NULL);
159570af302Sopenharmony_ci    EXPECT_EQ("send_0100", 0, ret);
160570af302Sopenharmony_ci    ret = pthread_join(cli, NULL);
161570af302Sopenharmony_ci    EXPECT_EQ("send_0100", 0, ret);
162570af302Sopenharmony_ci    ret = pthread_join(srv, NULL);
163570af302Sopenharmony_ci    EXPECT_EQ("send_0100", 0, ret);
164570af302Sopenharmony_ci    ret = pthread_barrier_destroy(&g_barrier);
165570af302Sopenharmony_ci    EXPECT_EQ("send_0100", 0, ret);
166570af302Sopenharmony_ci}
167570af302Sopenharmony_ci
168570af302Sopenharmony_ci/*
169570af302Sopenharmony_ci * @tc.name      : send_0200
170570af302Sopenharmony_ci * @tc.desc      : Verify that client send failed when parameter is invalid
171570af302Sopenharmony_ci * @tc.level     : Level 2
172570af302Sopenharmony_ci */
173570af302Sopenharmony_civoid send_0200(void)
174570af302Sopenharmony_ci{
175570af302Sopenharmony_ci    pthread_t srv;
176570af302Sopenharmony_ci    pthread_t cli;
177570af302Sopenharmony_ci    int ret = pthread_barrier_init(&g_barrier, 0, 2);
178570af302Sopenharmony_ci    EXPECT_EQ("send_0200", 0, ret);
179570af302Sopenharmony_ci    ret = pthread_create(&srv, NULL, SampleServerNullTask, NULL);
180570af302Sopenharmony_ci    EXPECT_EQ("send_0200", 0, ret);
181570af302Sopenharmony_ci    ret = pthread_create(&cli, NULL, SampleClientNullTask, NULL);
182570af302Sopenharmony_ci    EXPECT_EQ("send_0200", 0, ret);
183570af302Sopenharmony_ci    ret = pthread_join(cli, NULL);
184570af302Sopenharmony_ci    EXPECT_EQ("send_0200", 0, ret);
185570af302Sopenharmony_ci    ret = pthread_join(srv, NULL);
186570af302Sopenharmony_ci    EXPECT_EQ("send_0200", 0, ret);
187570af302Sopenharmony_ci    ret = pthread_barrier_destroy(&g_barrier);
188570af302Sopenharmony_ci    EXPECT_EQ("send_0200", 0, ret);
189570af302Sopenharmony_ci}
190570af302Sopenharmony_ci
191570af302Sopenharmony_ciTEST_FUN G_Fun_Array[] = {send_0100, send_0200};
192570af302Sopenharmony_ciint main(int argc, char *argv[])
193570af302Sopenharmony_ci{
194570af302Sopenharmony_ci    int num = sizeof(G_Fun_Array) / sizeof(TEST_FUN);
195570af302Sopenharmony_ci    for (int pos = 0; pos < num; ++pos) {
196570af302Sopenharmony_ci        G_Fun_Array[pos]();
197570af302Sopenharmony_ci    }
198570af302Sopenharmony_ci
199570af302Sopenharmony_ci    return t_status;
200570af302Sopenharmony_ci}