Пример #1
0
            /// <summary>
            /// This method is used to build a root node object from a byte array.
            /// </summary>
            /// <param name="fileContent">Specify the byte array.</param>
            /// <returns>Return a root node object build from the byte array.</returns>
            public RootNodeObject Build(byte[] fileContent)
            {
                RootNodeObject rootNode = new RootNodeObject();

                rootNode.Signature                  = new SignatureObject();
                rootNode.DataSize                   = new DataSizeObject();
                rootNode.DataSize.DataSize          = (ulong)fileContent.Length;
                rootNode.ExGuid                     = new ExGuid(SequenceNumberGenerator.GetCurrentSerialNumber(), Guid.NewGuid());
                rootNode.IntermediateNodeObjectList = ChunkingFactory.CreateChunkingInstance(fileContent).Chunking();
                return(rootNode);
            }
        /// <summary>
        /// This method is used to create the instance of AbstractChunking.
        /// </summary>
        /// <param name="nodeObject">Specify the root node object.</param>
        /// <returns>The instance of AbstractChunking.</returns>
        public static AbstractChunking CreateChunkingInstance(RootNodeObject nodeObject)
        {
            byte[] fileContent = nodeObject.GetContent().ToArray();

            if (EditorsTableUtils.IsEditorsTableHeader(fileContent))
            {
                return(null);
            }

            if (ZipHeader.IsFileHeader(fileContent, 0))
            {
                return(new ZipFilesChunking(fileContent));
            }
            else
            {
                // For SharePoint Server 2013 compatible SUTs, always using the RDC Chunking method in the current test suite involved file resources.
                if (SharedContext.Current.CellStorageVersionType.MinorVersion >= 2)
                {
                    return(new RDCAnalysisChunking(fileContent));
                }

                // For SharePoint Server 2010 SP2 compatible SUTs, chunking method depends on file content and size. So first try using the simple chunking.
                AbstractChunking returnChunking = new SimpleChunking(fileContent);

                List <IntermediateNodeObject> nodes = returnChunking.Chunking();
                if (nodeObject.IntermediateNodeObjectList.Count == nodes.Count)
                {
                    bool isDataSizeMatching = true;
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        if (nodeObject.IntermediateNodeObjectList[i].DataSize.DataSize != nodes[i].DataSize.DataSize)
                        {
                            isDataSizeMatching = false;
                            break;
                        }
                    }

                    if (isDataSizeMatching)
                    {
                        return(returnChunking);
                    }
                }

                // If the intermediate count number or data size does not equals, then try to use RDC chunking method.
                return(new RDCAnalysisChunking(fileContent));
            }
        }
        /// <summary>
        /// This method is used to create the instance of AbstractChunking.
        /// </summary>
        /// <param name="nodeObject">Specify the root node object.</param>
        /// <returns>The instance of AbstractChunking.</returns>
        public static AbstractChunking CreateChunkingInstance(RootNodeObject nodeObject)
        {
            byte[] fileContent = nodeObject.GetContent().ToArray();

            if (EditorsTableUtils.IsEditorsTableHeader(fileContent))
            {
                return null;
            }

            if (ZipHeader.IsFileHeader(fileContent, 0))
            {
                return new ZipFilesChunking(fileContent);
            }
            else
            {
                // For SharePoint Server 2013 compatible SUTs, always using the RDC Chunking method in the current test suite involved file resources.
                if (SharedContext.Current.CellStorageVersionType.MinorVersion >= 2)
                {
                    return new RDCAnalysisChunking(fileContent);
                }

                // For SharePoint Server 2010 SP2 compatible SUTs, chunking method depends on file content and size. So first try using the simple chunking.  
                AbstractChunking returnChunking = new SimpleChunking(fileContent);

                List<IntermediateNodeObject> nodes = returnChunking.Chunking();
                if (nodeObject.IntermediateNodeObjectList.Count == nodes.Count)
                {
                    bool isDataSizeMatching = true;
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        if (nodeObject.IntermediateNodeObjectList[i].DataSize.DataSize != nodes[i].DataSize.DataSize)
                        {
                            isDataSizeMatching = false;
                            break;
                        }
                    }

                    if (isDataSizeMatching)
                    {
                        return returnChunking;
                    }
                }

                // If the intermediate count number or data size does not equals, then try to use RDC chunking method.
                return new RDCAnalysisChunking(fileContent);
            }
        }
Пример #4
0
            /// <summary>
            /// This method is used to create ObjectGroupObjectData instance from a root node object.
            /// </summary>
            /// <param name="node">Specify the node object.</param>
            /// <returns>Return the ObjectGroupObjectData instance.</returns>
            private ObjectGroupObjectData CreateObjectData(RootNodeObject node)
            {
                ObjectGroupObjectData objectData = new ObjectGroupObjectData();

                objectData.CellIDArray = new CellIDArray(0u, null);

                List <ExGuid> extendedGuidList = new List <ExGuid>();

                foreach (IntermediateNodeObject child in node.IntermediateNodeObjectList)
                {
                    extendedGuidList.Add(child.ExGuid);
                }

                objectData.ObjectExGUIDArray = new ExGUIDArray(extendedGuidList);
                objectData.Data = new BinaryItem(node.SerializeToByteList());

                return(objectData);
            }
        /// <summary>
        /// This method is used to analyze the chunk for simple chunk.
        /// </summary>
        /// <param name="rootNode">Specify the root node object which is needed to be analyzed.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public override void AnalyzeChunking(RootNodeObject rootNode, ITestSite site)
        {
            if (rootNode.DataSize.DataSize <= 1024 * 1024)
            {
                // These would be something ignored for MOSS2010, when the file size is less than 1MB.
                // In this case the server will response data without signature, but to be consistent with the behavior,
                // The Simple chunk still will be used, but empty signature check will be ignored.
                return;
            }
            else if (rootNode.DataSize.DataSize <= 250 * 1024 * 1024)
            {
                foreach (IntermediateNodeObject interNode in rootNode.IntermediateNodeObjectList)
                {
                    SignatureObject expect = this.GetSignature(interNode.DataNodeObjectData.ObjectData);
                    SignatureObject realValue = interNode.Signature;
                    if (!expect.Equals(interNode.Signature))
                    {
                        site.Assert.Fail("Expect the signature value {0}, but actual value is {1}", expect.ToString(), realValue.ToString());
                    }

                    site.Assert.IsTrue(interNode.DataSize.DataSize <= 1024 * 1024, "The size of each chunk should be equal or less than 1MB for simple chunk.");

                    site.Assert.AreEqual<ulong>(
                            (ulong)interNode.GetContent().Count,
                            interNode.DataSize.DataSize,
                            "Expect the data size value equal the number represented by the chunk.");

                    site.Assert.IsNotNull(
                        interNode.DataNodeObjectData,
                        "The Object References array of the Intermediate Node Object associated with this Data Node Object MUST have a single entry which MUST be the Object ID of the Data Node Object.");
                }

                site.Log.Add(LogEntryKind.Debug, "All the intermediate signature value matches.");

                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                {
                    MsfsshttpdCapture.VerifySimpleChunk(SharedContext.Current.Site);
                }
            }
            else
            {
                throw new NotImplementedException("When the file size is larger than 250MB, because the signature method is not implemented, the analysis method is also not implemented.");
            }
        }
Пример #6
0
        /// <summary>
        /// This method is used to analyze the chunk for simple chunk.
        /// </summary>
        /// <param name="rootNode">Specify the root node object which is needed to be analyzed.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public override void AnalyzeChunking(RootNodeObject rootNode, ITestSite site)
        {
            if (rootNode.DataSize.DataSize <= 1024 * 1024)
            {
                // These would be something ignored for MOSS2010, when the file size is less than 1MB.
                // In this case the server will response data without signature, but to be consistent with the behavior,
                // The Simple chunk still will be used, but empty signature check will be ignored.
                return;
            }
            else if (rootNode.DataSize.DataSize <= 250 * 1024 * 1024)
            {
                foreach (IntermediateNodeObject interNode in rootNode.IntermediateNodeObjectList)
                {
                    SignatureObject expect    = this.GetSignature(interNode.DataNodeObjectData.ObjectData);
                    SignatureObject realValue = interNode.Signature;
                    if (!expect.Equals(interNode.Signature))
                    {
                        site.Assert.Fail("Expect the signature value {0}, but actual value is {1}", expect.ToString(), realValue.ToString());
                    }

                    site.Assert.IsTrue(interNode.DataSize.DataSize <= 1024 * 1024, "The size of each chunk should be equal or less than 1MB for simple chunk.");

                    site.Assert.AreEqual <ulong>(
                        (ulong)interNode.GetContent().Count,
                        interNode.DataSize.DataSize,
                        "Expect the data size value equal the number represented by the chunk.");

                    site.Assert.IsNotNull(
                        interNode.DataNodeObjectData,
                        "The Object References array of the Intermediate Node Object associated with this Data Node Object MUST have a single entry which MUST be the Object ID of the Data Node Object.");
                }

                site.Log.Add(LogEntryKind.Debug, "All the intermediate signature value matches.");

                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                {
                    MsfsshttpdCapture.VerifySimpleChunk(SharedContext.Current.Site);
                }
            }
            else
            {
                throw new NotImplementedException("When the file size is larger than 250MB, because the signature method is not implemented, the analysis method is also not implemented.");
            }
        }
        /// <summary>
        /// This method is used to analyze the chunk for the RDC analysis chunk method.
        /// </summary>
        /// <param name="rootNode">Specify the root node object which is needed to be analyzed.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public override void AnalyzeChunking(RootNodeObject rootNode, TestTools.ITestSite site)
        {
            List<IntermediateNodeObject> expectList = this.Chunking();

            foreach (IntermediateNodeObject nodeObject in rootNode.IntermediateNodeObjectList)
            {
                IntermediateNodeObject expect = expectList.First();

                if (!expect.Signature.Equals(nodeObject.Signature))
                {
                    site.Assert.Fail("For the RDC chunk method expect the signature {0}, actual signature {1}", expect.ToString(), nodeObject.Signature.ToString());
                }

                if (expect.DataSize.DataSize != nodeObject.DataSize.DataSize)
                {
                    site.Assert.Fail("For the RDC chunk method expect the chunk size, actual chunk size {1}", expect.DataSize.DataSize, nodeObject.DataSize.DataSize);
                }

                expectList.RemoveAt(0);
            }

            // If runs here, then all the requirements related for RDC analysis can be captured.
            MsfsshttpdCapture.VerifyRdcAnalysisChunk(SharedContext.Current.Site);
        }
Пример #8
0
        /// <summary>
        /// This method is used to analyze the chunk for the RDC analysis chunk method.
        /// </summary>
        /// <param name="rootNode">Specify the root node object which is needed to be analyzed.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public override void AnalyzeChunking(RootNodeObject rootNode, TestTools.ITestSite site)
        {
            List <IntermediateNodeObject> expectList = this.Chunking();

            foreach (IntermediateNodeObject nodeObject in rootNode.IntermediateNodeObjectList)
            {
                IntermediateNodeObject expect = expectList.First();

                if (!expect.Signature.Equals(nodeObject.Signature))
                {
                    site.Assert.Fail("For the RDC chunk method expect the signature {0}, actual signature {1}", expect.ToString(), nodeObject.Signature.ToString());
                }

                if (expect.DataSize.DataSize != nodeObject.DataSize.DataSize)
                {
                    site.Assert.Fail("For the RDC chunk method expect the chunk size, actual chunk size {1}", expect.DataSize.DataSize, nodeObject.DataSize.DataSize);
                }

                expectList.RemoveAt(0);
            }

            // If runs here, then all the requirements related for RDC analysis can be captured.
            MsfsshttpdCapture.VerifyRdcAnalysisChunk(SharedContext.Current.Site);
        }
        /// <summary>
        /// This method is used to verify the root node related requirements.
        /// </summary>
        /// <param name="instance">Specify the intermediate node instance.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public void VerifyRootNodeObject(RootNodeObject instance, ITestSite site)
        {
            // If the instance is not null and there are no parsing errors, then the RootNodeObject related adapter requirements can be directly captured.
            if (null == instance)
            {
                site.Assert.Fail("The instance of type RootNodeObject is null due to parsing error or type casting error.");
            }

            // Verify the stream object header related requirements.
            this.ExpectStreamObjectHeaderStart(instance.StreamObjectHeaderStart, instance.GetType(), site);

            // Capture requirement MS-FSSHTTPD_R37, if stream object start type is StreamObjectHeaderStart32bit. 
            site.CaptureRequirement(
                     "MS-FSSHTTPD",
                     37,
                     @"[In Root Node Object Data] Root Node Start (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of  0x00, Compound of 0x1, Type of 0x20, and Length of 0x00.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R38
            site.CaptureRequirementIfAreEqual<ushort>(
                     0x104,
                     LittleEndianBitConverter.ToUInt16(instance.StreamObjectHeaderStart.SerializeToByteList().ToArray(), 0),
                     "MS-FSSHTTPD",
                     38,
                     @"[In Root Node Object Data] Root Node Start (2 bytes): The value of this field[Root Node Start] MUST be 0x0104.");

            // Directly capture requirement MS-FSSHTTPD_R38, if all above asserts pass. 
            site.CaptureRequirementIfAreEqual<Type>(
                     typeof(StreamObjectHeaderStart16bit),
                     instance.DataSize.StreamObjectHeaderStart.GetType(),
                     "MS-FSSHTTPD",
                     43,
                     @"[In Root Node Object Data] Data Size Header (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of  0x00, Compound of 0x0, Type of 0x22, and Length of 0x08 (the size, in bytes, of Data Size).");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R8010
            site.CaptureRequirementIfAreEqual<uint>(
                     0x1110,
                     LittleEndianBitConverter.ToUInt16(instance.DataSize.StreamObjectHeaderStart.SerializeToByteList().ToArray(), 0),
                     "MS-FSSHTTPD",
                     8010,
                     @"[In Root Node Object Data] Data Size Header (2 bytes): The value of this field[Data Size Header] MUST be 0x1110.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R39
            site.CaptureRequirementIfAreEqual<Type>(
                     typeof(StreamObjectHeaderStart16bit),
                     instance.Signature.StreamObjectHeaderStart.GetType(),
                     "MS-FSSHTTPD",
                     39,
                     @"[In Root Node Object Data] Signature Header (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of 0x00, Compound of 0x0, Type of 0x21, and Length equal to the size of Signature Data.");

            // Verify the stream object header end related requirements.
            this.ExpectStreamObjectHeaderEnd(instance.StreamObjectHeaderEnd, instance.GetType(), site);
            this.ExpectCompoundObject(instance.StreamObjectHeaderStart, site);

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R45
            site.CaptureRequirementIfAreEqual<Type>(
                     typeof(StreamObjectHeaderEnd8bit),
                     instance.StreamObjectHeaderEnd.GetType(),
                     "MS-FSSHTTPD",
                     45,
                     @"[In Root Node Object Data] Root Node End (1 byte): An 8-bit stream object header end, as specified in [MS-FSSHTTPB] section 2.2.1.5.3, that specifies a stream object of type 0x20.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R46
            site.CaptureRequirementIfAreEqual<byte>(
                     0x81,
                     instance.StreamObjectHeaderEnd.SerializeToByteList()[0],
                     "MS-FSSHTTPD",
                     46,
                     @"[In Root Node Object Data] Root Node End (1 byte): The value of this field[Root Node End] MUST be 0x81.");
        }
            /// <summary>
            /// This method is used to create ObjectGroupObjectData instance from a root node object.
            /// </summary>
            /// <param name="node">Specify the node object.</param>
            /// <returns>Return the ObjectGroupObjectData instance.</returns>
            private ObjectGroupObjectData CreateObjectData(RootNodeObject node)
            {
                ObjectGroupObjectData objectData = new ObjectGroupObjectData();

                objectData.CellIDArray = new CellIDArray(0u, null);

                List<ExGuid> extendedGuidList = new List<ExGuid>();
                foreach (IntermediateNodeObject child in node.IntermediateNodeObjectList)
                {
                    extendedGuidList.Add(child.ExGuid);
                }

                objectData.ObjectExGUIDArray = new ExGUIDArray(extendedGuidList);
                objectData.Data = new BinaryItem(node.SerializeToByteList());

                return objectData;
            }
        /// <summary>
        /// This method is used to verify the requirements related with the RootNodeObject type.
        /// </summary>
        /// <param name="rootNode">Specify the RootNodeObject instance.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public static void VerifyRootNodeObject(RootNodeObject rootNode, ITestSite site)
        {
            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R44
            site.CaptureRequirementIfAreEqual<ulong>(
                     (ulong)rootNode.GetContent().Count,
                     rootNode.DataSize.DataSize,
                     "MS-FSSHTTPD",
                     44,
                     @"[In Root Node Object Data] Data Size (8 bytes): An unsigned 64-bit integer that specifies the size of the file data represented by this Root Node Object.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R49
            site.CaptureRequirementIfAreEqual<ulong>(
                     (ulong)rootNode.GetContent().Count,
                     rootNode.DataSize.DataSize,
                     "MS-FSSHTTPD",
                     49,
                     @"[In Root Node Object References] The sum of the Data Size values from all of the Intermediate Node Objects MUST equal the Data Size specified in the Object Data of this Root Node Object.");

            // When after build the Root node object successfully, the following requirements can be directly captured.
            site.CaptureRequirement(
                     "MS-FSSHTTPD",
                     48,
                     @"[In Root Node Object References] Each Object Extended GUID MUST specify an Intermediate Node Object.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R8011
            site.CaptureRequirement(
                     "MS-FSSHTTPD",
                     8011,
                     @"[In Root Node Object References] The Object Extended GUID Array, as specified in [MS-FSSHTTPB] section 2.2.1.12.6.4, of the Root Node Object MUST specify an ordered set of Object Extended GUIDs. ");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R8012
            site.CaptureRequirement(
                     "MS-FSSHTTPD",
                     8012,
                     @"[In Root Node Object References] Object Extended GUID Array entries MUST be ordered based on the sequential file bytes represented by each Node Object.");
        }
Пример #12
0
            /// <summary>
            /// This method is used to build intermediate node object from an list of object group data element.
            /// </summary>
            /// <param name="objectGroupList">Specify the list of object group data elements.</param>
            /// <param name="dataObj">Specify the object group object.</param>
            /// <param name="intermediateGuid">Specify the intermediate extended GUID.</param>
            /// <returns>Return the intermediate node object.</returns>
            public IntermediateNodeObject Build(List <ObjectGroupDataElementData> objectGroupList, ObjectGroupObjectData dataObj, ExGuid intermediateGuid)
            {
                IntermediateNodeObject node     = null;
                RootNodeObject         rootNode = null;

                int index = 0;

                if (StreamObject.TryGetCurrent <IntermediateNodeObject>(dataObj.Data.Content.ToArray(), ref index, out node))
                {
                    if (dataObj.ObjectExGUIDArray == null)
                    {
                        throw new InvalidOperationException("Failed to build intermediate node because the object extend GUID array does not exist.");
                    }

                    node.ExGuid = intermediateGuid;

                    // Contain a single Data Node Object.
                    if (dataObj.ObjectExGUIDArray.Count.DecodedValue == 1u)
                    {
                        ObjectGroupObjectDeclare dataNodeDeclare;
                        ObjectGroupObjectData    dataNodeData = this.FindByExGuid(objectGroupList, dataObj.ObjectExGUIDArray.Content[0], out dataNodeDeclare);
                        BinaryItem data = dataNodeData.Data;

                        node.DataNodeObjectData         = new DataNodeObjectData(data.Content.ToArray(), 0, (int)data.Length.DecodedValue);
                        node.DataNodeObjectData.ExGuid  = dataObj.ObjectExGUIDArray.Content[0];
                        node.IntermediateNodeObjectList = null;

                        if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                        {
                            MsfsshttpdCapture.VerifyObjectGroupObjectDataForDataNodeObject(dataNodeData, dataNodeDeclare, objectGroupList, SharedContext.Current.Site);
                        }
                    }
                    else
                    {
                        // Contain a list of IntermediateNodeObject
                        node.IntermediateNodeObjectList = new List <IntermediateNodeObject>();
                        node.DataNodeObjectData         = null;
                        foreach (ExGuid extGuid in dataObj.ObjectExGUIDArray.Content)
                        {
                            ObjectGroupObjectDeclare intermediateDeclare;
                            ObjectGroupObjectData    intermediateData = this.FindByExGuid(objectGroupList, extGuid, out intermediateDeclare);
                            node.IntermediateNodeObjectList.Add(new IntermediateNodeObjectBuilder().Build(objectGroupList, intermediateData, extGuid));

                            if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                            {
                                MsfsshttpdCapture.VerifyObjectGroupObjectDataForIntermediateNode(intermediateData, intermediateDeclare, objectGroupList, SharedContext.Current.Site);
                            }
                        }
                    }
                }
                else if (StreamObject.TryGetCurrent <RootNodeObject>(dataObj.Data.Content.ToArray(), ref index, out rootNode))
                {
                    // In Sub chunking for larger than 1MB zip file, MOSS2010 could return RootNodeObject.
                    // For easy further process, the rootNode will be replaced by intermediate node instead.
                    node = new IntermediateNodeObject();
                    node.IntermediateNodeObjectList = new List <IntermediateNodeObject>();
                    node.DataSize           = rootNode.DataSize;
                    node.ExGuid             = rootNode.ExGuid;
                    node.Signature          = rootNode.Signature;
                    node.DataNodeObjectData = null;
                    foreach (ExGuid extGuid in dataObj.ObjectExGUIDArray.Content)
                    {
                        ObjectGroupObjectDeclare intermediateDeclare;
                        ObjectGroupObjectData    intermediateData = this.FindByExGuid(objectGroupList, extGuid, out intermediateDeclare);
                        node.IntermediateNodeObjectList.Add(new IntermediateNodeObjectBuilder().Build(objectGroupList, intermediateData, extGuid));

                        if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                        {
                            MsfsshttpdCapture.VerifyObjectGroupObjectDataForIntermediateNode(intermediateData, intermediateDeclare, objectGroupList, SharedContext.Current.Site);
                        }
                    }
                }
                else
                {
                    throw new InvalidOperationException("In the ObjectGroupDataElement cannot only contain the RootNodeObject or IntermediateNodeOBject.");
                }

                return(node);
            }
 /// <summary>
 /// This method is used to analyze the chunk.
 /// </summary>
 /// <param name="rootNode">Specify the root node object which is needed to be analyzed.</param>
 /// <param name="site">Specify the ITestSite instance.</param>
 public abstract void AnalyzeChunking(RootNodeObject rootNode, ITestSite site);
Пример #14
0
 /// <summary>
 /// This method is used to analyze the chunk.
 /// </summary>
 /// <param name="rootNode">Specify the root node object which is needed to be analyzed.</param>
 /// <param name="site">Specify the ITestSite instance.</param>
 public abstract void AnalyzeChunking(RootNodeObject rootNode, ITestSite site);
Пример #15
0
            /// <summary>
            /// This method is used to build a root node object from an object group data element list with the specified root extended GUID.
            /// </summary>
            /// <param name="objectGroupList">Specify the object group data element list.</param>
            /// <param name="rootExGuid">Specify the root extended GUID.</param>
            /// <returns>Return a root node object build from the object group data element list.</returns>
            private RootNodeObject Build(List <ObjectGroupDataElementData> objectGroupList, ExGuid rootExGuid)
            {
                ObjectGroupObjectDeclare rootDeclare;
                ObjectGroupObjectData    root = this.FindByExGuid(objectGroupList, rootExGuid, out rootDeclare);

                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                {
                    MsfsshttpdCapture.VerifyObjectCount(root, SharedContext.Current.Site);
                }

                int            index    = 0;
                RootNodeObject rootNode = null;

                if (StreamObject.TryGetCurrent <RootNodeObject>(root.Data.Content.ToArray(), ref index, out rootNode))
                {
                    rootNode.ExGuid = rootExGuid;

                    foreach (ExGuid extGuid in root.ObjectExGUIDArray.Content)
                    {
                        ObjectGroupObjectDeclare intermediateDeclare;
                        ObjectGroupObjectData    intermediateData = this.FindByExGuid(objectGroupList, extGuid, out intermediateDeclare);
                        rootNode.IntermediateNodeObjectList.Add(new IntermediateNodeObject.IntermediateNodeObjectBuilder().Build(objectGroupList, intermediateData, extGuid));

                        // Capture the intermediate related requirements
                        if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                        {
                            MsfsshttpdCapture.VerifyObjectGroupObjectDataForIntermediateNode(intermediateData, intermediateDeclare, objectGroupList, SharedContext.Current.Site);
                            MsfsshttpdCapture.VerifyIntermediateNodeObject(rootNode.IntermediateNodeObjectList.Last(), SharedContext.Current.Site);
                        }
                    }

                    if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                    {
                        // Capture the root node related requirements.
                        MsfsshttpdCapture.VerifyObjectGroupObjectDataForRootNode(root, rootDeclare, objectGroupList, SharedContext.Current.Site);
                        MsfsshttpdCapture.VerifyRootNodeObject(rootNode, SharedContext.Current.Site);
                    }
                }
                else
                {
                    // If there is only one object in the file, SharePoint Server 2010 does not return the Root Node Object, but an Intermediate Node Object at the beginning.
                    // At this case, we will add the root node object for the further parsing.
                    rootNode        = new RootNodeObject();
                    rootNode.ExGuid = rootExGuid;

                    rootNode.IntermediateNodeObjectList.Add(new IntermediateNodeObject.IntermediateNodeObjectBuilder().Build(objectGroupList, root, rootExGuid));
                    rootNode.DataSize          = new DataSizeObject();
                    rootNode.DataSize.DataSize = (ulong)rootNode.IntermediateNodeObjectList.Sum(o => (float)o.DataSize.DataSize);
                }

                // Capture all the signature related requirements.
                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                {
                    AbstractChunking chunking = ChunkingFactory.CreateChunkingInstance(rootNode);

                    if (chunking != null)
                    {
                        chunking.AnalyzeChunking(rootNode, SharedContext.Current.Site);
                    }
                }

                return(rootNode);
            }
Пример #16
0
        /// <summary>
        /// This method is used to verify the root node related requirements.
        /// </summary>
        /// <param name="instance">Specify the intermediate node instance.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public void VerifyRootNodeObject(RootNodeObject instance, ITestSite site)
        {
            // If the instance is not null and there are no parsing errors, then the RootNodeObject related adapter requirements can be directly captured.
            if (null == instance)
            {
                site.Assert.Fail("The instance of type RootNodeObject is null due to parsing error or type casting error.");
            }

            // Verify the stream object header related requirements.
            this.ExpectStreamObjectHeaderStart(instance.StreamObjectHeaderStart, instance.GetType(), site);

            // Capture requirement MS-FSSHTTPD_R37, if stream object start type is StreamObjectHeaderStart32bit.
            site.CaptureRequirement(
                "MS-FSSHTTPD",
                37,
                @"[In Root Node Object Data] Root Node Start (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of  0x00, Compound of 0x1, Type of 0x20, and Length of 0x00.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R38
            site.CaptureRequirementIfAreEqual <ushort>(
                0x104,
                LittleEndianBitConverter.ToUInt16(instance.StreamObjectHeaderStart.SerializeToByteList().ToArray(), 0),
                "MS-FSSHTTPD",
                38,
                @"[In Root Node Object Data] Root Node Start (2 bytes): The value of this field[Root Node Start] MUST be 0x0104.");

            // Directly capture requirement MS-FSSHTTPD_R38, if all above asserts pass.
            site.CaptureRequirementIfAreEqual <Type>(
                typeof(StreamObjectHeaderStart16bit),
                instance.DataSize.StreamObjectHeaderStart.GetType(),
                "MS-FSSHTTPD",
                43,
                @"[In Root Node Object Data] Data Size Header (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of  0x00, Compound of 0x0, Type of 0x22, and Length of 0x08 (the size, in bytes, of Data Size).");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R8010
            site.CaptureRequirementIfAreEqual <uint>(
                0x1110,
                LittleEndianBitConverter.ToUInt16(instance.DataSize.StreamObjectHeaderStart.SerializeToByteList().ToArray(), 0),
                "MS-FSSHTTPD",
                8010,
                @"[In Root Node Object Data] Data Size Header (2 bytes): The value of this field[Data Size Header] MUST be 0x1110.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R39
            site.CaptureRequirementIfAreEqual <Type>(
                typeof(StreamObjectHeaderStart16bit),
                instance.Signature.StreamObjectHeaderStart.GetType(),
                "MS-FSSHTTPD",
                39,
                @"[In Root Node Object Data] Signature Header (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of 0x00, Compound of 0x0, Type of 0x21, and Length equal to the size of Signature Data.");

            // Verify the stream object header end related requirements.
            this.ExpectStreamObjectHeaderEnd(instance.StreamObjectHeaderEnd, instance.GetType(), site);
            this.ExpectCompoundObject(instance.StreamObjectHeaderStart, site);

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R45
            site.CaptureRequirementIfAreEqual <Type>(
                typeof(StreamObjectHeaderEnd8bit),
                instance.StreamObjectHeaderEnd.GetType(),
                "MS-FSSHTTPD",
                45,
                @"[In Root Node Object Data] Root Node End (1 byte): An 8-bit stream object header end, as specified in [MS-FSSHTTPB] section 2.2.1.5.3, that specifies a stream object of type 0x20.");

            // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R46
            site.CaptureRequirementIfAreEqual <byte>(
                0x81,
                instance.StreamObjectHeaderEnd.SerializeToByteList()[0],
                "MS-FSSHTTPD",
                46,
                @"[In Root Node Object Data] Root Node End (1 byte): The value of this field[Root Node End] MUST be 0x81.");
        }
        /// <summary>
        /// This method is used to analyze the chunk.
        /// </summary>
        /// <param name="rootNode">Specify the root node object which will be analyzed.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public override void AnalyzeChunking(RootNodeObject rootNode, ITestSite site)
        {
            List<IntermediateNodeObject> cloneList = new List<IntermediateNodeObject>(rootNode.IntermediateNodeObjectList);

            while (cloneList.Count != 0)
            {
                IntermediateNodeObject nodeObject = cloneList.First();
                byte[] content = nodeObject.DataNodeObjectData.ObjectData;

                if (cloneList.Count == 1)
                {
                    if (content.Length > 1048576)
                    {
                        throw new NotImplementedException("If the final chunk is larger than 1MB, the signature method is not implemented.");
                    }

                    // Only final chunk left
                    SignatureObject expect = this.GetSHA1Signature(content);
                    if (!expect.Equals(nodeObject.Signature))
                    {
                        site.Assert.Fail("For the Zip file, final part chunk expect the signature {0}, actual signature {1}", expect.ToString(), nodeObject.Signature.ToString());
                    }

                    // Verify the less than 1MB final part related requirements
                    if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                    {
                        MsfsshttpdCapture.VerifySmallFinalChunk(SharedContext.Current.Site);
                    }
                }
                else
                {
                    if (ZipHeader.IsFileHeader(content, 0))
                    {
                        byte[] dataFileSignatureBytes;
                        byte[] header = this.AnalyzeFileHeader(content, 0, out dataFileSignatureBytes);
                        int headerLength = header.Length;
                        int compressedSize = (int)this.GetCompressedSize(dataFileSignatureBytes);

                        if (headerLength + compressedSize <= 4096)
                        {
                            IntermediateNodeObject expectNode = new IntermediateNodeObject.IntermediateNodeObjectBuilder().Build(content, this.GetSingleChunkSignature(header, dataFileSignatureBytes));
                            if (!expectNode.Signature.Equals(nodeObject.Signature))
                            {
                                site.Assert.Fail("For the Zip file, when zip file is less than 4096, expect the signature {0}, actual signature {1}", expectNode.Signature.ToString(), nodeObject.Signature.ToString());
                            }

                            // Verify the zip file less than 4096 bytes
                            MsfsshttpdCapture.VerifyZipFileLessThan4096Bytes(SharedContext.Current.Site);
                        }
                        else
                        {
                            SignatureObject expectHeader = this.GetSHA1Signature(header);
                            if (!expectHeader.Equals(nodeObject.Signature))
                            {
                                site.Assert.Fail("For the Zip file header, expect the signature {0}, actual signature {1}", expectHeader.ToString(), nodeObject.Signature.ToString());
                            }

                            // Remove the header node
                            cloneList.RemoveAt(0);

                            // Then expect the next is file content node
                            nodeObject = cloneList.First();

                            // Here having something need to be distinguished between the MOSS2010 and MOSS2013
                            if (nodeObject.DataNodeObjectData == null && nodeObject.IntermediateNodeObjectList != null)
                            {
                                // This situation could most happens for MOSS2010, we fake intermediate node instead of the root node when the zip file size is larger than 1M.
                                // In the current stage, this kind of signature algorithm is not mentioned in the open specification, so leave this verify blank.
                            }
                            else if (nodeObject.DataNodeObjectData != null)
                            {
                                site.Assert.AreEqual<ulong>(
                                            (ulong)compressedSize,
                                            nodeObject.DataSize.DataSize,
                                            "The Data Size of the Intermediate Node Object MUST be the total number of bytes represented by the chunk.");

                                SignatureObject contentSignature = new SignatureObject();
                                contentSignature.SignatureData = new BinaryItem(dataFileSignatureBytes);
                                if (!contentSignature.Equals(nodeObject.Signature))
                                {
                                    site.Assert.Fail("For the Zip file content, expect the signature {0}, actual signature {1}", contentSignature.ToString(), nodeObject.Signature.ToString());
                                }

                                // Verify the zip file larger than 4096 bytes and less than 1MB.
                                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                                {
                                    MsfsshttpdCapture.VerifyZipFileHeaderAndContentSignature(SharedContext.Current.Site);
                                    MsfsshttpdCapture.VerifyIntermediateNodeForZipFileChunk(SharedContext.Current.Site);
                                }
                            }
                            else
                            {
                                throw new InvalidOperationException("The DataNodeObjectData and IntermediateNodeObjectList cannot be null at the same time.");
                            }
                        }
                    }
                }

                cloneList.RemoveAt(0);
            }
        }
Пример #18
0
            /// <summary>
            /// This method is used to build a root node object from an object group data element list with the specified root extended GUID.
            /// </summary>
            /// <param name="objectGroupList">Specify the object group data element list.</param>
            /// <param name="rootExGuid">Specify the root extended GUID.</param>
            /// <returns>Return a root node object build from the object group data element list.</returns>
            private RootNodeObject Build(List<ObjectGroupDataElementData> objectGroupList, ExGuid rootExGuid)
            {
                ObjectGroupObjectDeclare rootDeclare;
                ObjectGroupObjectData root = this.FindByExGuid(objectGroupList, rootExGuid, out rootDeclare);

                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                {
                    MsfsshttpdCapture.VerifyObjectCount(root, SharedContext.Current.Site);
                }

                int index = 0;
                RootNodeObject rootNode = null;

                if (StreamObject.TryGetCurrent<RootNodeObject>(root.Data.Content.ToArray(), ref index, out rootNode))
                {
                    rootNode.ExGuid = rootExGuid;

                    foreach (ExGuid extGuid in root.ObjectExGUIDArray.Content)
                    {
                        ObjectGroupObjectDeclare intermediateDeclare;
                        ObjectGroupObjectData intermediateData = this.FindByExGuid(objectGroupList, extGuid, out intermediateDeclare);
                        rootNode.IntermediateNodeObjectList.Add(new IntermediateNodeObject.IntermediateNodeObjectBuilder().Build(objectGroupList, intermediateData, extGuid));

                        // Capture the intermediate related requirements
                        if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                        {
                            MsfsshttpdCapture.VerifyObjectGroupObjectDataForIntermediateNode(intermediateData, intermediateDeclare, objectGroupList, SharedContext.Current.Site);
                            MsfsshttpdCapture.VerifyIntermediateNodeObject(rootNode.IntermediateNodeObjectList.Last(), SharedContext.Current.Site);
                        }
                    }

                    if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                    {
                        // Capture the root node related requirements. 
                        MsfsshttpdCapture.VerifyObjectGroupObjectDataForRootNode(root, rootDeclare, objectGroupList, SharedContext.Current.Site);
                        MsfsshttpdCapture.VerifyRootNodeObject(rootNode, SharedContext.Current.Site);
                    }
                }
                else
                {
                    // If there is only one object in the file, SharePoint Server 2010 does not return the Root Node Object, but an Intermediate Node Object at the beginning.
                    // At this case, we will add the root node object for the further parsing.
                    rootNode = new RootNodeObject();
                    rootNode.ExGuid = rootExGuid;
                    
                    rootNode.IntermediateNodeObjectList.Add(new IntermediateNodeObject.IntermediateNodeObjectBuilder().Build(objectGroupList, root, rootExGuid));
                    rootNode.DataSize = new DataSizeObject();
                    rootNode.DataSize.DataSize = (ulong)rootNode.IntermediateNodeObjectList.Sum(o => (float)o.DataSize.DataSize);
                }

                // Capture all the signature related requirements.
                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                {
                    AbstractChunking chunking = ChunkingFactory.CreateChunkingInstance(rootNode);

                    if (chunking != null)
                    {
                        chunking.AnalyzeChunking(rootNode, SharedContext.Current.Site);
                    }
                }
                
                return rootNode;
            }
Пример #19
0
 /// <summary>
 /// This method is used to build a root node object from a byte array.
 /// </summary>
 /// <param name="fileContent">Specify the byte array.</param>
 /// <returns>Return a root node object build from the byte array.</returns>
 public RootNodeObject Build(byte[] fileContent)
 {
     RootNodeObject rootNode = new RootNodeObject();
     rootNode.Signature = new SignatureObject();
     rootNode.DataSize = new DataSizeObject();
     rootNode.DataSize.DataSize = (ulong)fileContent.Length;
     rootNode.ExGuid = new ExGuid(SequenceNumberGenerator.GetCurrentSerialNumber(), Guid.NewGuid());
     rootNode.IntermediateNodeObjectList = ChunkingFactory.CreateChunkingInstance(fileContent).Chunking();
     return rootNode;
 }
Пример #20
0
        /// <summary>
        /// This method is used to analyze the chunk.
        /// </summary>
        /// <param name="rootNode">Specify the root node object which will be analyzed.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public override void AnalyzeChunking(RootNodeObject rootNode, ITestSite site)
        {
            List <IntermediateNodeObject> cloneList = new List <IntermediateNodeObject>(rootNode.IntermediateNodeObjectList);

            while (cloneList.Count != 0)
            {
                IntermediateNodeObject nodeObject = cloneList.First();
                byte[] content = nodeObject.DataNodeObjectData.ObjectData;

                if (cloneList.Count == 1)
                {
                    if (content.Length > 1048576)
                    {
                        throw new NotImplementedException("If the final chunk is larger than 1MB, the signature method is not implemented.");
                    }

                    // Only final chunk left
                    SignatureObject expect = this.GetSHA1Signature(content);
                    if (!expect.Equals(nodeObject.Signature))
                    {
                        site.Assert.Fail("For the Zip file, final part chunk expect the signature {0}, actual signature {1}", expect.ToString(), nodeObject.Signature.ToString());
                    }

                    // Verify the less than 1MB final part related requirements
                    if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                    {
                        MsfsshttpdCapture.VerifySmallFinalChunk(SharedContext.Current.Site);
                    }
                }
                else
                {
                    if (ZipHeader.IsFileHeader(content, 0))
                    {
                        byte[] dataFileSignatureBytes;
                        byte[] header         = this.AnalyzeFileHeader(content, 0, out dataFileSignatureBytes);
                        int    headerLength   = header.Length;
                        int    compressedSize = (int)this.GetCompressedSize(dataFileSignatureBytes);

                        if (headerLength + compressedSize <= 4096)
                        {
                            IntermediateNodeObject expectNode = new IntermediateNodeObject.IntermediateNodeObjectBuilder().Build(content, this.GetSingleChunkSignature(header, dataFileSignatureBytes));
                            if (!expectNode.Signature.Equals(nodeObject.Signature))
                            {
                                site.Assert.Fail("For the Zip file, when zip file is less than 4096, expect the signature {0}, actual signature {1}", expectNode.Signature.ToString(), nodeObject.Signature.ToString());
                            }

                            // Verify the zip file less than 4096 bytes
                            MsfsshttpdCapture.VerifyZipFileLessThan4096Bytes(SharedContext.Current.Site);
                        }
                        else
                        {
                            SignatureObject expectHeader = this.GetSHA1Signature(header);
                            if (!expectHeader.Equals(nodeObject.Signature))
                            {
                                site.Assert.Fail("For the Zip file header, expect the signature {0}, actual signature {1}", expectHeader.ToString(), nodeObject.Signature.ToString());
                            }

                            // Remove the header node
                            cloneList.RemoveAt(0);

                            // Then expect the next is file content node
                            nodeObject = cloneList.First();

                            // Here having something need to be distinguished between the MOSS2010 and MOSS2013
                            if (nodeObject.DataNodeObjectData == null && nodeObject.IntermediateNodeObjectList != null)
                            {
                                // This situation could most happens for MOSS2010, we fake intermediate node instead of the root node when the zip file size is larger than 1M.
                                // In the current stage, this kind of signature algorithm is not mentioned in the open specification, so leave this verify blank.
                            }
                            else if (nodeObject.DataNodeObjectData != null)
                            {
                                site.Assert.AreEqual <ulong>(
                                    (ulong)compressedSize,
                                    nodeObject.DataSize.DataSize,
                                    "The Data Size of the Intermediate Node Object MUST be the total number of bytes represented by the chunk.");

                                SignatureObject contentSignature = new SignatureObject();
                                contentSignature.SignatureData = new BinaryItem(dataFileSignatureBytes);
                                if (!contentSignature.Equals(nodeObject.Signature))
                                {
                                    site.Assert.Fail("For the Zip file content, expect the signature {0}, actual signature {1}", contentSignature.ToString(), nodeObject.Signature.ToString());
                                }

                                // Verify the zip file larger than 4096 bytes and less than 1MB.
                                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                                {
                                    MsfsshttpdCapture.VerifyZipFileHeaderAndContentSignature(SharedContext.Current.Site);
                                    MsfsshttpdCapture.VerifyIntermediateNodeForZipFileChunk(SharedContext.Current.Site);
                                }
                            }
                            else
                            {
                                throw new InvalidOperationException("The DataNodeObjectData and IntermediateNodeObjectList cannot be null at the same time.");
                            }
                        }
                    }
                }

                cloneList.RemoveAt(0);
            }
        }