Skip to content
Permalink
Browse files
test: add test cases about filter (#15)
  • Loading branch information
tzssangglass committed May 27, 2021
1 parent aeda437 commit 88c0c267f0593d7c8ce17533b2917f8768e99ad2
Show file tree
Hide file tree
Showing 9 changed files with 466 additions and 9 deletions.
@@ -39,7 +39,7 @@ public A6Request decode(ByteBuffer buffer) {
try {
type = buffer.get();
} catch (BufferUnderflowException e) {
logger.error("receive empty data");
logger.warn("receive empty data");
return new A6ErrRequest(Code.BAD_REQUEST);
}

@@ -51,7 +51,7 @@ public A6Request decode(ByteBuffer buffer) {
body = getBody(buffer);
a6ConfigRequest = A6ConfigRequest.from(body);
} catch (BufferUnderflowException | IndexOutOfBoundsException e) {
logger.error("receive error data length");
logger.warn("receive error data length");
return new A6ErrRequest(Code.BAD_REQUEST);
}
return a6ConfigRequest;
@@ -68,7 +68,7 @@ public A6Request decode(ByteBuffer buffer) {
break;
}

logger.error("receive unsupported type: {}", type);
logger.warn("receive unsupported type: {}", type);
return new A6ErrRequest(Code.BAD_REQUEST);
}

@@ -53,7 +53,6 @@ public void handle(A6Request request, A6Response response) {
PluginFilterChain chain = createFilterChain(req);
A6Conf config = new A6Conf(req, chain);
cache.put(token, config);

}

private PluginFilterChain createFilterChain(Req req) {
@@ -62,7 +61,11 @@ private PluginFilterChain createFilterChain(Req req) {
TextEntry conf = req.conf(i);
PluginFilter filter = filters.get(conf.name());
if (Objects.isNull(filter)) {
logger.error("receive undefined filter: {}, skip it", conf.name());
logger.warn("receive undefined filter: {}, skip it", conf.name());
continue;
}
if (chainFilters.contains(filter)) {
logger.warn("skip the same filter: {}", conf.name());
continue;
}
chainFilters.add(filter);
@@ -48,7 +48,7 @@ public A6ConfigHandler createConfigHandler(Cache<Long, A6Conf> cache, ObjectProv
List<PluginFilter> pluginFilterList = beanProvider.orderedStream().collect(Collectors.toList());
Map<String, PluginFilter> filterMap = new HashMap<>();
for (PluginFilter filter : pluginFilterList) {
filterMap.put(filter.getClass().getSimpleName(), filter);
filterMap.put(filter.name(), filter);
}
return new A6ConfigHandler(cache, filterMap);
}
@@ -76,7 +76,7 @@ public Dispatcher createDispatcher(A6ConfigHandler configHandler, A6HttpCallHand
httpCallHandler.handle(request, response);
return response;
default:
logger.error("can not dispatch type: {}", request.getType());
logger.warn("can not dispatch type: {}", request.getType());
response = new A6ErrResponse(Code.SERVICE_UNAVAILABLE);
return response;
}
@@ -46,7 +46,7 @@ public void handle(A6Request request, A6Response response) {
long confToken = ((HttpRequest) request).getConfToken();
A6Conf conf = cache.getIfPresent(confToken);
if (Objects.isNull(conf)) {
logger.error("cannot find conf-token: {}", confToken);
logger.warn("cannot find conf token: {}", confToken);
A6ErrResponse errResponse = new A6ErrResponse(Code.CONF_TOKEN_NOT_FOUND);
rsp.setErrResponse(errResponse);
return;
@@ -0,0 +1,197 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.apisix.plugin.runner.handler;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.flatbuffers.FlatBufferBuilder;
import io.github.api7.A6.PrepareConf.Req;
import io.github.api7.A6.TextEntry;
import org.apache.apisix.plugin.runner.A6Conf;
import org.apache.apisix.plugin.runner.A6ConfigRequest;
import org.apache.apisix.plugin.runner.A6ConfigResponse;
import org.apache.apisix.plugin.runner.HttpRequest;
import org.apache.apisix.plugin.runner.HttpResponse;
import org.apache.apisix.plugin.runner.filter.PluginFilter;
import org.apache.apisix.plugin.runner.filter.PluginFilterChain;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@ExtendWith(OutputCaptureExtension.class)
@DisplayName("test add filter")
class A6ConfigHandlerTest {

Cache<Long, A6Conf> cache;

Map<String, PluginFilter> filters;

A6ConfigHandler a6ConfigHandler;

@BeforeEach
void setUp() {
filters = new HashMap<>();
filters.put("FooFilter", new PluginFilter() {
@Override
public String name() {
return "FooFilter";
}

@Override
public Mono<Void> filter(HttpRequest request, HttpResponse response, PluginFilterChain chain) {
return chain.filter(request, response);
}

@Override
public int getOrder() {
return 0;
}
});

filters.put("CatFilter", new PluginFilter() {
@Override
public String name() {
return "CatFilter";
}

@Override
public Mono<Void> filter(HttpRequest request, HttpResponse response, PluginFilterChain chain) {
return chain.filter(request, response);
}

@Override
public int getOrder() {
return 1;
}
});
cache = CacheBuilder.newBuilder().expireAfterWrite(3600, TimeUnit.SECONDS).maximumSize(1000).build();
a6ConfigHandler = new A6ConfigHandler(cache, filters);
}

@Test
@DisplayName("test add filter by prepare conf")
void testAddFilter1() {
FlatBufferBuilder builder = new FlatBufferBuilder();
int name = builder.createString("FooFilter");
int value = builder.createString("Bar");
int conf = TextEntry.createTextEntry(builder, name, value);
int confVector = Req.createConfVector(builder, new int[]{conf});
Req.startReq(builder);
Req.addConf(builder, confVector);
builder.finish(Req.endReq(builder));
Req req = Req.getRootAsReq(builder.dataBuffer());

A6ConfigRequest request = new A6ConfigRequest(req);
A6ConfigResponse response = new A6ConfigResponse(0L);
a6ConfigHandler.handle(request, response);

A6Conf config = cache.getIfPresent(0L);
Assertions.assertNotNull(config.getChain());
Assertions.assertEquals(config.getChain().getFilters().size(), 1);
Assertions.assertEquals(config.getChain().getFilters().get(0).getOrder(), 0);
Assertions.assertEquals(config.get("FooFilter"), "Bar");

}

@Test
@DisplayName("test filter sort by it's order")
void testAddFilter2() {
FlatBufferBuilder builder = new FlatBufferBuilder();
int cat = builder.createString("CatFilter");
int dog = builder.createString("Dog");
int filter2 = TextEntry.createTextEntry(builder, cat, dog);

int foo = builder.createString("FooFilter");
int bar = builder.createString("Bar");
int filter1 = TextEntry.createTextEntry(builder, foo, bar);

int confVector = Req.createConfVector(builder, new int[]{filter1, filter2});
Req.startReq(builder);
Req.addConf(builder, confVector);
builder.finish(Req.endReq(builder));
Req req = Req.getRootAsReq(builder.dataBuffer());

A6ConfigRequest request = new A6ConfigRequest(req);
A6ConfigResponse response = new A6ConfigResponse(0L);
a6ConfigHandler.handle(request, response);

A6Conf config = cache.getIfPresent(0L);
Assertions.assertEquals(config.getChain().getFilters().size(), 2);
Assertions.assertEquals(config.getChain().getFilters().get(0).getOrder(), 0);
Assertions.assertEquals(config.getChain().getFilters().get(1).getOrder(), 1);
}

@Test
@DisplayName("test skip the same name filter")
void testAddFilter3(CapturedOutput capturedOutput) {
FlatBufferBuilder builder = new FlatBufferBuilder();
int foo1 = builder.createString("FooFilter");
int bar1 = builder.createString("Bar1");
int filter1 = TextEntry.createTextEntry(builder, foo1, bar1);

int foo2 = builder.createString("FooFilter");
int bar2 = builder.createString("Bar2");
int filter2 = TextEntry.createTextEntry(builder, foo2, bar2);

int confVector = Req.createConfVector(builder, new int[]{filter1, filter2});
Req.startReq(builder);
Req.addConf(builder, confVector);
builder.finish(Req.endReq(builder));
Req req = Req.getRootAsReq(builder.dataBuffer());

A6ConfigRequest request = new A6ConfigRequest(req);
A6ConfigResponse response = new A6ConfigResponse(0L);
a6ConfigHandler.handle(request, response);

A6Conf config = cache.getIfPresent(0L);
Assertions.assertEquals(config.getChain().getFilters().size(), 1);
Assertions.assertTrue(capturedOutput.getOut().contains("skip the same filter: FooFilter"));
}

@Test
@DisplayName("test receive undefined filter")
void testAddFilter4(CapturedOutput capturedOutput) {
FlatBufferBuilder builder = new FlatBufferBuilder();
int foo = builder.createString("UndefinedFilter");
int bar = builder.createString("Bar");
int filter = TextEntry.createTextEntry(builder, foo, bar);

int confVector = Req.createConfVector(builder, new int[]{filter});
Req.startReq(builder);
Req.addConf(builder, confVector);
builder.finish(Req.endReq(builder));
Req req = Req.getRootAsReq(builder.dataBuffer());

A6ConfigRequest request = new A6ConfigRequest(req);
A6ConfigResponse response = new A6ConfigResponse(0L);
a6ConfigHandler.handle(request, response);

A6Conf config = cache.getIfPresent(0L);
Assertions.assertEquals(config.getChain().getFilters().size(), 0);
Assertions.assertTrue(capturedOutput.getOut().contains("receive undefined filter: UndefinedFilter, skip it"));
}
}

0 comments on commit 88c0c26

Please sign in to comment.