From 18114d6a5d5111cdaa6e86d99ea9f97205076c1d Mon Sep 17 00:00:00 2001 From: Julien Kerihuel Date: Fri, 27 Aug 2010 10:43:21 +0000 Subject: [PATCH] Include a mapitest test suite / challenge for lzxpress The idea of this test is to check if lzxpress compressed blobs provided by OpenChange are the same than Outlook ones. The test takes a Outlook->Exchange capture file with compressed blob, pull the content, decompressed the content, recompress the content and check the output for differing bytes. This challenge code should give us good information when lzxpress compress code is fixed. Additionally you can uncomment the compression code in libmapi/emsmdb.c to do further testing. --- Makefile | 7 +- config.mk.in | 3 +- ..._Outlook_2007_in_ModifyRecipients_comp.dat | Bin 0 -> 432 bytes ...Outlook_2007_in_Tables_operations_comp.dat | Bin 0 -> 436 bytes utils/mapitest/module.c | 22 +++ utils/mapitest/modules/module_lzxpress.c | 152 ++++++++++++++++++ 6 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 utils/mapitest/data/lzxpress/001_Outlook_2007_in_ModifyRecipients_comp.dat create mode 100644 utils/mapitest/data/lzxpress/002_Outlook_2007_in_Tables_operations_comp.dat create mode 100644 utils/mapitest/modules/module_lzxpress.c diff --git a/Makefile b/Makefile index 7a6952e3..3ff2961b 100644 --- a/Makefile +++ b/Makefile @@ -1339,9 +1339,12 @@ mapitest: libmapi \ mapitest-install: mapitest $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL) -m 0755 bin/mapitest $(DESTDIR)$(bindir) + $(INSTALL) -d $(DESTDIR)$(datadir)/mapitest/lzxpress + $(INSTALL) -m 0644 utils/mapitest/data/lzxpress/* $(DESTDIR)$(datadir)/mapitest/lzxpress/ mapitest-uninstall: rm -f $(DESTDIR)$(bindir)/mapitest + rm -rf $(DESTDIR)$(datadir)/mapitest mapitest-clean: rm -f bin/mapitest @@ -1380,6 +1383,7 @@ bin/mapitest: utils/mapitest/mapitest.o \ utils/mapitest/modules/module_errorchecks.o \ utils/mapitest/modules/module_lcid.o \ utils/mapitest/modules/module_mapidump.o \ + utils/mapitest/modules/module_lzxpress.o \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt $(SUBUNIT_LIBS) @@ -1404,7 +1408,8 @@ utils/mapitest/proto.h: \ utils/mapitest/modules/module_noserver.c \ utils/mapitest/modules/module_errorchecks.c \ utils/mapitest/modules/module_lcid.c \ - utils/mapitest/modules/module_mapidump.c + utils/mapitest/modules/module_mapidump.c \ + utils/mapitest/modules/module_lzxpress.c @echo "Generating $@" @./script/mkproto.pl --private=utils/mapitest/mapitest_proto.h --public=utils/mapitest/proto.h $^ diff --git a/config.mk.in b/config.mk.in index e368e72d..741ef230 100644 --- a/config.mk.in +++ b/config.mk.in @@ -34,7 +34,8 @@ CFLAGS=@CFLAGS@ @COMPILER_OPTIONS_C@ @ASSERT_DEFINITION@ @SUBUNIT_CFLAGS@ \ -DDEFAULT_LDIF=\"$(datadir)/setup/profiles\" \ -DMAPISTORE_LDIF=\"$(datadir)/setup/mapistore\" \ -DMAPISTORE_BACKEND_INSTALLDIR=\"$(libdir)/mapistore_backends\" \ - -DMAPISTORE_MAPPING_PATH=\"$(prefix)/private/mapistore\" + -DMAPISTORE_MAPPING_PATH=\"$(prefix)/private/mapistore\" \ + -DLZXPRESS_DATADIR=\"$(datadir)/mapitest/lzxpress\" # This value should be determined by configure at some point SHLIBEXT=so diff --git a/utils/mapitest/data/lzxpress/001_Outlook_2007_in_ModifyRecipients_comp.dat b/utils/mapitest/data/lzxpress/001_Outlook_2007_in_ModifyRecipients_comp.dat new file mode 100644 index 0000000000000000000000000000000000000000..119c40d46e006d951038e58156629882ec8a094f GIT binary patch literal 432 zcmXAlu}fQV5XV2i_mY=jV-g)C2sYWYEi|G_A_SwDDk-HZwv;Y0q!05;^u74<;@~7s z{t0e6${#X`E-Nuf&@H)&B9X_roQQu}-D9e3aR9^7%?0~ma}`^|YAnd!VAoO*JX zA6G422|ouZh_52As#DPoelH3Ubnat1WRpB3xXD6(*nR|FwfGL zn~%bfw$UK>LOM-1_1ak~TXMbZO4~}?tpg@LtVl~XU1w3S(P7O@O*?k0k*-*|d9xxL z(zM*Bq!#TGbU`1n*`9!=#OD@O8i=|xfhMjxEkWo!sEI4HpfoGFD6#C(Fe`ZU?Uq6&{{Qv*} literal 0 HcmV?d00001 diff --git a/utils/mapitest/data/lzxpress/002_Outlook_2007_in_Tables_operations_comp.dat b/utils/mapitest/data/lzxpress/002_Outlook_2007_in_Tables_operations_comp.dat new file mode 100644 index 0000000000000000000000000000000000000000..d4b8b66c8d4fe2f085c85f378a483c7d8e8b3111 GIT binary patch literal 436 zcmXYt%S#(^5XV2i-)}crtx~a}tRCFlGzUvSiK!J_izVjY{=CRWMLQ{=*FwxwbdUCrp#E6Kr zNlyF{STG|@5V9UYEeSk7LCz-cD+YXr4wOvl{Pw`3EpUjfC^`d0JWEd?#n-^aN)H~1 zqLqx&Obo-Jkp}u1BF`tAd8R3_%$m&{-;>*Wr6S)v7MNl7fZi4z5I##s3^2*!j)upI z%<>cdZX{B~?v(I!*9+AdSQSJCB#(O3XS0F)wp??ipVN?LHMGj_DoNXL)g;E0KK~0T zq`7__-^3t}u}l4m)t|QR-%HU`=Tew+xXd_Q*@(14WE9dyW!_O;Y^kLz^1eWNE? zPHoP{InQ#OrPcpYlFzW(#q%4z{x!Y@X}uf7Xwm#9ESJk+CHxnb_aDMnI@BieZ?wJD K68TZhj+Pe=&S$&; literal 0 HcmV?d00001 diff --git a/utils/mapitest/module.c b/utils/mapitest/module.c index 8e5a00da..0a930f15 100644 --- a/utils/mapitest/module.c +++ b/utils/mapitest/module.c @@ -41,6 +41,7 @@ _PUBLIC_ uint32_t mapitest_register_modules(struct mapitest *mt) ret += module_errorchecks_init(mt); ret += module_lcid_init(mt); ret += module_mapidump_init(mt); + ret += module_lzxpress_init(mt); return ret; } @@ -456,3 +457,24 @@ _PUBLIC_ uint32_t module_mapidump_init(struct mapitest *mt) return MAPITEST_SUCCESS; } + + +/** + \details Initialise the language code / ID test suite + + \param mt pointer to the top-level mapitest structure + + \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR + */ +_PUBLIC_ uint32_t module_lzxpress_init(struct mapitest *mt) +{ + struct mapitest_suite *suite = NULL; + + suite = mapitest_suite_init(mt, "LZXPRESS", "lzxpress algorithm test suite", false); + + mapitest_suite_add_test(suite, "VALIDATE-001", "Validate LZXPRESS implementation using sample file 001", mapitest_lzxpress_validate_test_001); + + mapitest_suite_register(mt, suite); + + return MAPITEST_SUCCESS; +} diff --git a/utils/mapitest/modules/module_lzxpress.c b/utils/mapitest/modules/module_lzxpress.c new file mode 100644 index 00000000..d5c0609e --- /dev/null +++ b/utils/mapitest/modules/module_lzxpress.c @@ -0,0 +1,152 @@ +/* + Stand-alone MAPI testsuite + + OpenChange Project - LZXPRESS compression/decompression + + Copyright (C) Julien Kerihuel 2010 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "utils/mapitest/mapitest.h" +#include "utils/mapitest/proto.h" +#include "gen_ndr/ndr_exchange.h" +#include "libmapi/libmapi_private.h" + +/** + \file module_lzxpress.c + + \brief LZXPRESS compression and decompression test suite + */ + + +_PUBLIC_ bool mapitest_lzxpress_validate_test_001(struct mapitest *mt) +{ + bool ret = false; + char *filename = NULL; + DATA_BLOB blob; + uint8_t *data; + size_t size; + struct ndr_print *ndr_print; + struct ndr_pull *ndr_pull; + struct ndr_push *ndr_push; + struct ndr_push *ndr_comp; + struct ndr_push *ndr_rgbIn; + struct RPC_HEADER_EXT RPC_HEADER_EXT; + struct EcDoRpcExt2 r; + struct mapi2k7_request request; + NTSTATUS status; + enum ndr_err_code ndr_err; + + /* Step 1. Load Test File 001_Outlook_2007_in_ModifyRecipients_comp.dat */ + filename = talloc_asprintf(mt->mem_ctx, "%s/001_Outlook_2007_in_ModifyRecipients_comp.dat", LZXPRESS_DATADIR); +/* filename = talloc_asprintf(mt->mem_ctx, "%s/002_Outlook_2007_in_Tables_operations_comp.dat", LZXPRESS_DATADIR); */ + data = (uint8_t *)file_load(filename, &size, 0, mt->mem_ctx); + if (!data) { + perror(filename); + mapitest_print_retval_fmt(mt, "lzxpress_validate", "Error while loading %s", filename); + talloc_free(filename); + return false; + } + blob.data = data; + blob.length = size; + mapitest_print_retval_step(mt, "1", "Loading 001_Outlook_2007_in_ModifyRecipients_comp.dat", MAPI_E_SUCCESS); + + ndr_print = talloc_zero(mt->mem_ctx, struct ndr_print); + ndr_print->print = ndr_print_debug_helper; + ndr_print->depth = 1; + + /* Step 2. Pull 001_Outlook_2007_in_ModifyRecipients_comp.dat data */ + ndr_pull = ndr_pull_init_blob(&blob, mt->mem_ctx); + ndr_pull->flags |= LIBNDR_FLAG_REF_ALLOC; + + ndr_err = ndr_pull_EcDoRpcExt2(ndr_pull, NDR_IN, &r); + talloc_free(ndr_pull); + status = ndr_map_error2ntstatus(ndr_err); + if (NT_STATUS_IS_OK(status)) { + mapitest_print_retval_step(mt, "2", "001_Outlook_2007_in_ModifyRecipients_comp.dat", + MAPI_E_SUCCESS); + } else { + mapitest_print_retval_step(mt, "2", "Pulling 001_Outlook_2007_in_ModifyRecipients_comp.dat", + MAPI_E_CALL_FAILED); + return false; + } + + /* Step 4. Decompress data */ + blob.data = talloc_memdup(mt->mem_ctx, r.in.rgbIn, r.in.cbIn); + blob.length = r.in.cbIn; + ndr_pull = ndr_pull_init_blob(&blob, mt->mem_ctx); + ndr_set_flags(&ndr_pull->flags, LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_REF_ALLOC); + ndr_err = ndr_pull_mapi2k7_request(ndr_pull, NDR_SCALARS|NDR_BUFFERS, &request); + talloc_free(blob.data); + talloc_free(ndr_pull); + status = ndr_map_error2ntstatus(ndr_err); + if (NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Success\n")); + } + + /* Step 5. Recompress data */ + ndr_push = ndr_push_init_ctx(mt->mem_ctx); + ndr_set_flags(&ndr_push->flags, LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_REF_ALLOC); + ndr_push_mapi_request(ndr_push, NDR_SCALARS|NDR_BUFFERS, request.mapi_request); + ndr_comp = ndr_push_init_ctx(mt->mem_ctx); + ndr_push_lzxpress_compress(ndr_comp, ndr_push); + + /* Recreate complete blob */ + ndr_rgbIn = ndr_push_init_ctx(mt->mem_ctx); + ndr_set_flags(&ndr_rgbIn->flags, LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_REF_ALLOC); + + RPC_HEADER_EXT.Version = 0x0000; + RPC_HEADER_EXT.Flags = RHEF_Compressed|RHEF_Last; + RPC_HEADER_EXT.Size = ndr_comp->offset; + RPC_HEADER_EXT.SizeActual = ndr_push->offset; + ndr_push_RPC_HEADER_EXT(ndr_rgbIn, NDR_SCALARS|NDR_BUFFERS, &RPC_HEADER_EXT); + + ndr_push_bytes(ndr_rgbIn, ndr_comp->data, ndr_comp->offset); + talloc_free(ndr_comp); + + /* Compare Outlook and openchange rgbIn compressed blob */ + DEBUG(0, ("Outlook compressed blob size = 0x%x\n", r.in.cbIn)); + DEBUG(0, ("OpenChange compressed blob size = 0x%x\n", ndr_rgbIn->offset)); + ret = true; + { + int i; + int min; + + min = (ndr_rgbIn->offset >= r.in.cbIn) ? r.in.cbIn : ndr_rgbIn->offset; + DEBUG(0, ("Comparing Outlook and OpenChange blobs on 0x%x bytes\n", min)); + for (i = 0; i < min; i++) { + if (r.in.rgbIn[i] != ndr_rgbIn->data[i]) { + DEBUG(0, ("Bytes differs at offset 0x%x: Outlook (0x%.2x) OpenChange (0x%.2x)\n", + i, r.in.rgbIn[i], ndr_rgbIn->data[i])); + ret = false; + } + } + + } + + mapitest_print(mt, "Compressed rgbIn by Outlook\n"); + mapitest_print(mt, "==============================\n"); + dump_data(0, r.in.rgbIn, r.in.cbIn); + mapitest_print(mt, "==============================\n"); + + mapitest_print(mt, "Compressed rgbIn by OpenChange\n"); + mapitest_print(mt, "==============================\n"); + dump_data(0, ndr_rgbIn->data, ndr_rgbIn->offset); + mapitest_print(mt, "==============================\n"); + + talloc_free(ndr_rgbIn); + + return ret; +} -- 2.34.1